Last active
May 23, 2016 14:39
-
-
Save l0gicgate/45714a4389836179cfd3 to your computer and use it in GitHub Desktop.
Reusable action creators / reducers.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import axios from 'axios'; | |
class FetchActionCreators { | |
constructor(endpoint, actions) { | |
const [REQUEST, SUCCESS, FAILURE] = actions; | |
this.actions = { | |
REQUEST, | |
SUCCESS, | |
FAILURE, | |
}; | |
this.endpoint = endpoint; | |
} | |
fetch({ endpoint, params }) { | |
return (dispatch) => { | |
dispatch(this.request()); | |
return axios.get(endpoint || this.endpoint, { params }) | |
.then(res => { | |
dispatch(this.receive(this.actions.SUCCESS, res.data)); | |
}) | |
.catch((res) => { | |
dispatch(this.receive(this.actions.FAILURE)); | |
}); | |
}; | |
} | |
request() { | |
return { | |
type: this.actions.REQUEST, | |
}; | |
} | |
receive(type, data) { | |
return { | |
type, | |
data, | |
}; | |
} | |
} | |
export default FetchActionCreators; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class FetchReducerPrototype { | |
static initialState = { | |
data: null, | |
fetching: false, | |
receivedAt: null, | |
}; | |
constructor({ actions }) { | |
this.actions = actions; | |
return this.reducer; | |
} | |
reducer = (state = FetchReducerPrototype.initialState, action = {}) => { | |
switch (action.type) { | |
case this.actions.REQUEST: | |
return Object.assign({}, state, { | |
fetching: true, | |
}); | |
case this.actions.SUCCESS: | |
return Object.assign({}, state, { | |
data: action.data, | |
fetching: false, | |
receivedAt: Date.now(), | |
}); | |
case this.actions.FAILURE: | |
return Object.assign({}, state, { | |
fetching: false, | |
}); | |
default: | |
return state; | |
} | |
} | |
} | |
export default FetchReducerPrototype; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export default class ReducerChain { | |
constructor(reducers) { | |
this.reducers = reducers; | |
if (!Array.isArray(reducers)) { | |
throw new Error('To create a reducer chain you must pass in an array of functions.'); | |
} | |
return this.reducer; | |
} | |
reducer = (state, action) => { | |
let result = state; | |
for (let i = 0, len = this.reducers.length; i < len; i++) { | |
result = this.reducers[i](result, action); | |
} | |
return result; | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { combineReducers } from 'redux'; | |
import StreamsReducer from './StreamsReducer'; | |
import VideosReducer from './VideosReducer'; | |
const rootReducer = combineReducers({ | |
streams: StreamsReducer, | |
videos: VideosReducer, | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { PropTypes } from 'react'; | |
import { streamsFetchActions } from './StreamsReducer'; | |
class StreamsContainer extends React.Component { | |
static propTypes = { | |
dispatch: PropTypes.func.isRequired, | |
streams: PropTypes.object.isRequired, | |
}; | |
componentDidMount() { | |
const { dispatch, streams } = this.props; | |
if (!streams.fetching && !streams.data) { | |
dispatch(streamsFetchActions.fetch()); | |
} | |
} | |
render() { | |
const { streams } = this.props; | |
return streams.fetching ? | |
<div>Loading...</div> : | |
<div>{/* access streams via streams.data */}</div>; | |
} | |
} | |
function mapStateToProps(state) { | |
return { | |
streams: state.streams, | |
} | |
} | |
export default connect(mapStateToProps)(StreamsContainer); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import FetchActionCreators from './FetchActionCreators'; | |
import FetchReducerPrototype from './FetchReducerPrototype'; | |
const REQUEST_STREAMS = 'REQUEST_STREAMS'; | |
const RECEIVE_STREAMS_SUCCESS = 'RECEIVE_STREAMS_SUCCESS'; | |
const RECEIVE_STREAMS_FAILURE = 'RECEIVE_STREAMS_FAILURE'; | |
export const streamsFetchActions = new FetchActionCreators( | |
'http://yourwebsite.com/streams', | |
[ | |
REQUEST_STREAMS, | |
RECEIVE_STREAMS_SUCCESS, | |
RECEIVE_STREAMS_FAILURE, | |
] | |
); | |
export default new FetchReducerPrototype(streamsFetchActions); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { PropTypes } from 'react'; | |
import { videosFetchActions, modifyVideoData } from './VideosReducer'; | |
class VideosContainer extends React.Component { | |
static propTypes = { | |
dispatch: PropTypes.func.isRequired, | |
videos: PropTypes.object.isRequired, | |
}; | |
componentDidMount() { | |
const { dispatch, videos } = this.props; | |
if (!videos.fetching && !videos.data) { | |
dispatch(videosFetchActions.fetch()); | |
} | |
} | |
render() { | |
const { dispatch, videos } = this.props; | |
return videos.fetching ? | |
<div>Loading...</div> : | |
( | |
<div> | |
{/* access videos via videos.data */} | |
<button onClick={(e) => dispatch(modifyVideoData('Some value'))} /> | |
</div> | |
); | |
} | |
} | |
function mapStateToProps(state) { | |
return { | |
videos: state.videos, | |
} | |
} | |
export default connect(mapStateToProps)(VideosContainer); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import FetchActionCreators from './FetchActionCreators'; | |
import FetchReducerPrototype from './FetchReducerPrototype'; | |
import ReducerChain from './ReducerChain'; | |
const REQUEST_VIDEOS = 'REQUEST_VIDEOS'; | |
const RECEIVE_VIDEOS_SUCCESS = 'RECEIVE_VIDEOS_SUCCESS'; | |
const RECEIVE_VIDEOS_FAILURE = 'RECEIVE_VIDEOS_FAILURE'; | |
const MODIFY_VIDEO_DATA = 'MODIFY_VIDEO_DATA'; | |
export const videosFetchActions = new FetchActionCreators( | |
'http://yourwebsite.com/videos', | |
[ | |
REQUEST_VIDEOS, | |
RECEIVE_VIDEOS_SUCCESS, | |
RECEIVE_VIDEOS_FAILURE, | |
] | |
); | |
const fetchReducerPrototype = new FetchReducerPrototype(videosFetchActions); | |
const videoModifyingReducer(state, action) { | |
switch (action.type) { | |
case MODIFY_VIDEO_DATA: | |
return { | |
...state, | |
{ | |
data: { | |
...state.data, | |
someProp: action.someProp, | |
} | |
} | |
}); | |
default: | |
return state; | |
} | |
} | |
export function modifyVideoData(someValue) { | |
return { | |
type: MODIFY_VIDEO_DATA, | |
someProp: someValue, | |
} | |
} | |
export default new ReducerChain([ | |
fetchReducerPrototype, | |
videoModifyingReducer, | |
]); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment