Redux framework is using reducers to change app state in response to an action.
The key requirement is that a reducer cannot modify an existing state object; it must
Immutable.js ought to be used in each reducer as needed, e.g.
import {
ACTIVATE_LOCATION
} from './actions';
import Immutable from 'immutable';
export let ui = (state, action) => {
switch (action.type) {
case ACTIVATE_LOCATION:
state = Immutable
.fromJS(state)
.set('activeLocationId', action.id)
.toJS();
break;
}
return state;
};
However, there is a lot of overhead in this example: every time reducer action is invoked, it has to convert JavaScript object to an an instance of Immutable, mutate the resulting object and convert it back to JavaScript object.
A better approach is to have the initial state an instance of Immutable:
import {
ACTIVATE_LOCATION
} from './actions';
import Immutable from 'immutable';
let initialState = Immutable.Map([]);
export let ui = (state = initialState, action) => {
switch (action.type) {
case ACTIVATE_LOCATION:
state = state.set('activeLocationId', action.id);
break;
}
return state;
};
This way, you only need to convert the initial state to an instance of Immutable ounce. Then each reducer will treat it as an instance of Immutable and pass it down the line as an instance of Immutable. The catch is that now you need to cast the entire state to JavaScript before passing the values to the view context.
If you are performing multiple state mutations in a reducer, you might want to consider batching mutations using .withMutations.
To make things simpler, I have developed a redux-immutable library. It provides combineReducers function thats equivalent to the function of the same name in the redux package, except that it expect the initial state and all reducers to work with Immutable.js object.