Closed
Description
In the new docs (#140) we should clarify that any actions prefixed with @@
are not meant to be handled. For example, you should never try to handle @@INIT
. We might enforce that by slightly randomizing names (e.g. @@INIT_2hj3jh34
).
Handling @@INIT
manually will break hot reloading. It is invoked at every hot reload, so if you do your initial data transformation there, it won't work the second time.
I've seen people using @@INIT
to hydrate the plain objects received from the server into the Immutable state. Instead of handling @@INIT
, you need to consider one of two options:
- convert your whole plain object state to Immutable right away before passing it to Redux;
- check if the
state
is a plain object and usefromJS
before handling the action.
function myReducer(state = {}, action) {
if (!isImmutable(state)) { // some kind of typeof check here?
state = Immutable.fromJS(state);
}
...
}
It is easy to abstract this away with a createImmutableReducer
function like this:
export default function createImmutableReducer(initialState, handlers) {
return (state = initialState, action) => {
if (!isImmutable(state)) {
// Hydrate server plain object state
state = Immutable.fromJS(state);
}
const handler = handlers[action.type];
if (handler) {
state = handler(state, action);
}
if (!isImmutable(state)) {
throw new Error('Reducers must return Immutable objects.');
}
return state;
};
}
It can then be used for creating reducers from action constant -> handler
map.