Разделительные редукторы, работающие с одним и тем же срезом данных в Redux
У меня есть магазин, который имеет такую форму:
{
// ...data
user: {
warranties: {
W_1: ['O_1', 'O_2'],
W_2: ['O_3', 'O_4']
}
}
}
Где ключи начинаются с W_
являются гарантиями, ключи начинаются с O_
варианты.
Для каждой гарантии у меня есть один или несколько вариантов, связанных с ним, отношения в user.warranties
в форме: warranty => [options]
,
Чтобы добиться этого, я комбинирую мои редукторы так:
rootReducer = combineReducers({
// ...other main reducers
user: combineReducers({
// ...other user reducers
warranties
})
})
Теперь проблема заключается в том, что оба USER_WARRANTY
а также USER_OPTION
Действия обрабатываются одним и тем же редуктором, потому что:
Когда я добавляю опцию, мне нужно указать правильную запись гарантии.
И наоборот, когда я добавляю гарантию, мне нужно заполнить ее параметрами по умолчанию.
И, в конечном счете, они работают с одним и тем же фрагментом данных.
Итак warranties
редуктор, должен реагировать на оба действия, выглядя так:
export default function warranties(state = {}, action) {
switch (action.type) {
case USER_WARRANTIES_ADD:
// add warranty key to `user.warranties`
case USER_WARRANTIES_REMOVE:
// remove warranty key from `user.warranties`
case USER_OPTIONS_ADD:
// push option to `user.warranties[warrantyID]`
case USER_OPTIONS_REMOVE:
// remove option from `user.warranties[warrantyID]`
default:
return state
}
}
Я хотел бы разделить это на два редуктора, warranties
а также options
, но все же пусть они оперируют одним и тем же фрагментом данных.
В идеале я бы тогда написал свой корневой редуктор так:
rootReducer = combineReducers({
// ...other main reducers
user: combineReducers({
// ...other user reducers
warranties: magicalCombine({
warranties,
options
})
})
})
куда magicalCombine
это функция, которую мне трудно найти.
я пытался reduce-reducers
, но выглядит как второй редуктор (options
) никогда не достигается, и я на самом деле не уверен в этом, так как я не пытаюсь достичь плоского состояния, но на самом деле оперирую одним и тем же ключом.
1 ответ
Редуктор это просто функция, которая принимает state
а также action
и возвращает новый объект состояния, так что я думаю, что это будет делать то, что вы хотите..
rootReducer = combineReducers({
// ...other main reducers
user: combineReducers({
// ...other user reducers
warranties: (state, action) => {
// state is state.user.warranties
// we pass it to each reducer in turn and return the result
state = warranties(state, action);
return options(state, action);
}
})
})
использование reduReducers должно делать то же самое (я раньше этим не пользовался, но вот как это выглядит...)
rootReducer = combineReducers({
// ...other main reducers
user: combineReducers({
// ...other user reducers
warranties: reduceReducers(warranties, options)
})
})
combineReducers
from redux просто намеренно ограничен, чтобы передавать только значение свойства состояния, которое соответствует ключу в предоставленном ему объекте Redurs, это не совсем особенный другой способ. подробнее здесь.. https://redux.js.org/recipes/structuringreducers/beyondcombinereducers