@incoqnito.io/redux-immutable
v3.0.13
Published
redux-immutable is used to create an equivalent function of Redux combineReducers that works with Immutable.js state. Our version also enables you to add reducers at runtime to allow for efficient code splitting.
Downloads
2
Readme
redux-immutable
redux-immutable
is used to create an equivalent function of Redux combineReducers
that works with Immutable.js state.
When Redux createStore
reducer
is created using redux-immutable
then initialState
must be an instance of Immutable.Collection
.
Problem
When createStore
is invoked with initialState
that is an instance of Immutable.Collection
further invocation of reducer will produce an error:
The initialState argument passed to createStore has unexpected type of "Object". Expected argument to be an object with the following keys: "data"
This is because Redux combineReducers
treats state
object as a plain JavaScript object.
combineReducers
created using redux-immutable
uses Immutable.js API to iterate the state.
Usage
Create a store with initialState
set to an instance of Immutable.Collection
:
import {
combineReducers
} from 'redux-immutable';
import {
createStore
} from 'redux';
const initialState = Immutable.Map();
const rootReducer = combineReducers({});
const store = createStore(rootReducer, initialState);
By default, if state
is undefined
, rootReducer(state, action)
is called with state = Immutable.Map()
. A different default function can be provided as the second parameter to combineReducers(reducers, getDefaultState)
, for example:
const StateRecord = Immutable.Record({
foo: 'bar'
});
const rootReducer = combineReducers({foo: fooReducer}, StateRecord);
// rootReducer now has signature of rootReducer(state = StateRecord(), action)
// state now must always have 'foo' property with 'bar' as its default value
When using Immutable.Record
it is possible to delegate default values to child reducers:
const StateRecord = Immutable.Record({
foo: undefined
});
const rootReducer = combineReducers({foo: fooReducer}, StateRecord);
// state now must always have 'foo' property with its default value returned from fooReducer(undefined, action)
In general, getDefaultState
function must return an instance of Immutable.Record
or Immutable.Collection
that implements get
, set
and withMutations
methods. Such collections are List
, Map
and OrderedMap
.
Using with react-router-redux
react-router-redux
routeReducer
does not work with Immutable.js. You need to use a custom reducer:
import Immutable from 'immutable';
import {
LOCATION_CHANGE
} from 'react-router-redux';
const initialState = Immutable.fromJS({
locationBeforeTransitions: null
});
export default (state = initialState, action) => {
if (action.type === LOCATION_CHANGE) {
return state.set('locationBeforeTransitions', action.payload);
}
return state;
};
Pass a selector to access the payload state and convert it to a JavaScript object via the selectLocationState
option on syncHistoryWithStore
:
import {
browserHistory
} from 'react-router';
import {
syncHistoryWithStore
} from 'react-router-redux';
const history = syncHistoryWithStore(browserHistory, store, {
selectLocationState (state) {
return state.get('routing').toJS();
}
});
The 'routing'
path depends on the rootReducer
definition. This example assumes that routeReducer
is made available under routing
property of the rootReducer
.