За мой (весьма небольшой) опыт разработки на React и Redux столкнулся с двумя способами делать редюсеры:
1. Хранить state редюсера как обычный объект {}.
export default function myReducer(state = {}, action) {
switch(action.type) {
case types.MY_ACTION:
let newState = Object.assign({}, state);
newState.posts[action.payload.post.id].comments.push(action.payload.comment);
return newState;
default:
return state;
}
}
2. Хранить state редюсера как Immutable.js Map.
export default function myReducer(state = Map(), action) {
switch(action.type) {
case types.MY_ACTION:
let newState = state;
newState = newState.updateIn(['posts', action.payload.post.id, 'comments'], comments => {
return comments.push(fromJS(action.payload.comment));
});
return newState;
default:
return state;
}
}
Чем хорош способ 1 - понятно.
Во-первых, код редюсера получается проще. Хотя на странице Immutable.js написано "leading to much simpler application development", на деле все обстоит точно наоборот - код редюсера без Immutable проще и лаконичнее. А вот с Immutable код превращается в месиво, и здесь еще не самый удачный пример. И чтобы в таком месиве не допустить ошибку, требуется просто ювелирная внимательность.
Во-вторых, получаются проще компоненты. Ведь компоненты получают в пропсы отдельные части этого state и если он Immutable, то приходится везде делать
toJS()
и это опять же усложняет и может привести к ошибкам. А без Immutable это не нужно.
А в чем же преимущества способа 2?
Я вижу лишь одно - здесь нету копирования через
Object.assign.
(Да и то, я не знаю, как внутри устроен Immutable - может там наоборот копирование на каждом шаге.)
Чего я не понимаю? Какие еще есть преимущества есть у Immutable в state reducer'ов? Или это как раз дурацкая практика?