Last active
November 7, 2016 14:15
-
-
Save iMoses/39bb505d615774f923bd697869ee2a48 to your computer and use it in GitHub Desktop.
Immutable Records as stores (minimal example)
This file contains hidden or 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 stateRecord from './state-record'; | |
import { | |
FETCH_SEARCH_RESULTS_LOADING, | |
FETCH_SEARCH_RESULTS_SUCCESS, | |
FETCH_SEARCH_RESULTS_FAILURE, | |
} from './actions'; | |
export default { | |
stateRecord, | |
actionHandlers: { | |
[FETCH_SEARCH_RESULTS_LOADING]: onLoad, | |
[FETCH_SEARCH_RESULTS_SUCCESS]: onSuccess, | |
[FETCH_SEARCH_RESULTS_FAILURE]: onFailure, | |
} | |
}; | |
function onLoad(state, action) { | |
state.set('is_loading', true).set('search_query', action.payload.query); | |
} | |
function onSuccess(state, action) { | |
if (state.search_query === action.payload.query) | |
state.reset().set('search_query', action.payload.query) | |
.setSearchResults(action.payload.results); | |
} | |
function onFailure(state, action) { | |
if (state.search_query === action.payload.query) | |
state.reset().set('search_query', action.payload.query); | |
} |
This file contains hidden or 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 * as redux from 'redux'; | |
/** | |
* Custom method for creating immutable reducers out of a state record and an actions map | |
* @param stateRecord | |
* @param actionHandlers | |
* @return {function(state, action): state} | |
*/ | |
export function immutableReducer({ stateRecord, actionHandlers }) { | |
return (state, action) => action.type in actionHandlers | |
? state.withMutations(state => actionHandlers[action.type](state, action)) | |
: state; | |
} | |
/** | |
* Custom method for combining immutable reducers along side standard reducers | |
* @param reducers | |
* @return {*} | |
*/ | |
export function combineImmutableReducers(reducers) { | |
const immutable_reducers = {}; | |
Object.keys(reducers).forEach(key => { | |
immutable_reducers[key] = typeof reducers[key] === 'function' | |
? reducers[key] : immutableReducer(reducers[key]); | |
}); | |
return redux.combineReducers(immutable_reducers); | |
} | |
/** | |
* Overwrite `createStore` to support immutable reducers | |
* @param reducers | |
* @param initialState | |
* @param middlewares | |
* @return {*} | |
*/ | |
export function createStore(reducers, initialState={}, middlewares=[]) { | |
const createStore = redux.applyMiddleware(...middlewares)(redux.createStore); | |
if (typeof reducers === 'object') Object.keys(reducers).forEach(key => { | |
if (typeof reducers[key] === 'object') | |
initialState[key] = new (reducers[key].stateRecord)(initialState[key]); | |
}); | |
return createStore(combineImmutableReducers(reducers), initialState); | |
} |
This file contains hidden or 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 { Record, List } from 'immutable'; | |
import { SearchResultRecord } from './records'; | |
class stateRecord extends Record({ | |
page_index: 0, | |
search_query: '', | |
search_results: List([]), | |
is_loading: false, | |
}) { | |
constructor(props={}) { | |
super({ | |
...props, | |
search_results: stateRecord.searchResults(props.search_results || []) | |
}); | |
} | |
static searchResults(list=[]) { | |
return List(list.map(item => new SearchResultRecord(item))); | |
} | |
setSearchResults(list) { | |
return this.set('search_results', stateRecord.searchResults(list)); | |
} | |
get page_number() { | |
return this.page_index + 1; | |
} | |
get is_empty() { | |
return this.search_results.size === 0; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment