Ответ 1
Разница:
combineReducers
создает вложенное состояние statereduceReducers
создает состояние state
Рассмотрим следующие редукторы. Не существует типов действий, которые бы упростили ситуацию:
// this reducer adds a payload to state.sum
// and tracks total number of operations
function reducerAdd(state, payload) {
if (!state) state = { sum: 0, totalOperations: 0 }
if (!payload) return state
return {
...state,
sum: state.sum + payload,
totalOperations: state.totalOperations + 1
}
}
// this reducer multiplies state.product by payload
// and tracks total number of operations
function reducerMult(state, payload) {
if (!state) state = { product: 1, totalOperations: 0 }
if (!payload) return state
// 'product' might be undefined because of
// small caveat in 'reduceReducers', see below
const prev = state.product || 1
return {
...state,
product: prev * payload,
totalOperations: state.totalOperations + 1
}
}
combineReducers
Каждый редуктор получает независимую часть состояния (см. также http://redux.js.org/docs/api/combineReducers.html):
const rootReducer = combineReducers({
add: reducerAdd,
mult: reducerMult
})
const initialState = rootReducer(undefined)
/*
* {
* add: { sum: 0, totalOperations: 0 },
* mult: { product: 1, totalOperations: 0 },
* }
*/
const first = rootReducer(initialState, 4)
/*
* {
* add: { sum: 4, totalOperations: 1 },
* mult: { product: 4, totalOperations: 1 },
* }
*/
// This isn't interesting, let look at second call...
const second = rootReducer(first, 4)
/*
* {
* add: { sum: 8, totalOperations: 2 },
* mult: { product: 16, totalOperations: 2 },
* }
*/
// Now it obvious, that both reducers get their own
// piece of state to work with
reduceReducers
Все редукторы находятся в одном состоянии
const addAndMult = reduceReducers(reducerAdd, reducerMult)
const initial = addAndMult(undefined)
/*
* {
* sum: 0,
* totalOperations: 0
* }
*
* First, reducerAdd is called, which gives us initial state { sum: 0 }
* Second, reducerMult is called, which does not have payload, so it
* just returns state unchanged.
* That why there isn't any 'product' prop.
*/
const next = addAndMult(initial, 4)
/*
* {
* sum: 4,
* product: 4,
* totalOperations: 2
* }
*
* First, reducerAdd is called, which changes 'sum' = 0 + 4 = 4
* Second, reducerMult is called, which changes 'product' = 1 * 4 = 4
* Both reducers modify 'totalOperations'
*/
const final = addAndMult(next, 4)
/*
* {
* sum: 8,
* product: 16,
* totalOperations: 4
* }
*/
Примеры использования
combineReducers
- каждый редуктор управляет собственным срезом состояния (например,state.todos
иstate.logging
). Это полезно при создании корневого редуктора.reduceReducers
- каждый редуктор управляет одним и тем же состоянием. Это полезно при объединении нескольких редукторов, которые должны работать в одном и том же состоянии (это может случиться, например, при объединении нескольких редукторов, созданных с использованиемhandleAction
из redux-actions)
Отличие очевидно от формы конечного состояния.
Предостережения
В reduceReducers
есть небольшая оговорка: когда конечный редуктор вызывается с помощью state = undefined
, он должен вернуть исходное состояние. Однако только первый редуктор в цепочке получает undefined
, все остальные редукторы будут получать состояние от первого.