reduce-reducers の意味がわかりません。同じアクションを含む2つのリデューサー関数がある場合に使用する必要がありますか?
function reducerA(state, action){
switch(action.type):
...
case 'SAME_ACTION': {...state, field: state.field+1}
}
function reducerB(state, action){
switch(action.type):
...
case 'SAME_ACTION': {...state, field: state.field*2}
}
reduceReducer
およびreducerA
でreducerB
を呼び出し、{field: 0}
に対してアクション 'SAME_ACTION'が呼び出された場合、次の状態は{field: 2}
になりますか?
また、それは一種のレデューサーを連結しているように思えます(1つのキーの下でそれらをマージすることを意味します)。
私は正しいですか、またはreduceReducer
は別の目的に役立ちますか?
違いは:
combineReducers
はネストされた状態を作成しますreduceReducers
は、flat状態を作成します次の減速機を検討してください。物事を簡単にするためのアクションタイプはありません。
// 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
}
}
各レデューサーは、独立した状態を取得します( 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's look at second call...
const second = rootReducer(first, 4)
/*
* {
* add: { sum: 8, totalOperations: 2 },
* mult: { product: 16, totalOperations: 2 },
* }
*/
// Now it's obvious, that both reducers get their own
// piece of state to work with
すべてのレデューサーは同じ状態を共有します
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 doesn't have payload, so it
* just returns state unchanged.
* That's 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
)。これは、rootレデューサーを作成するときに役立ちます。reduceReducers
-各レデューサーは同じ状態を管理します。これは、同じ状態で動作するはずの複数のレデューサーをチェーンする場合に便利です(たとえば、 redux-actions からhandleAction
を使用して作成された複数のレデューサーを組み合わせる場合に発生する可能性があります)違いは、最終状態の形状から明らかです。
reduceReducers
には小さな注意事項があります:state = undefined
を指定してfinalレデューサーを呼び出すと、初期状態を返す必要があります。ただし、チェーンの最初のレデューサーのみがundefined
を取得し、他のすべてのレデューサーは最初のレデューサーから状態を受け取ります。
また、reduce-reducerが解決しようとしているものがわかりません。 @Tomášによって記述されたユースケースは、単純なReducerによって実現できます。結局のところ、Reducerはアプリの状態とアクションを受け入れ、新しいアプリの状態を含むオブジェクトを返すだけの関数です。たとえば、reduxが提供するcomposeReducersを使用する代わりに、以下を実行できます。
import combinationReducer from "./combinationReducer";
import endOfPlayReducer from "./endOfPlayReducer";
import feedbackReducer from "./feedbackReducer";
function combineReducers(appState, action) {
return {
combination: combinationReducer(appState, action),
feedbacks: feedbackReducer(appState, action),
endOfPlay: endOfPlayReducer(appState, action)
};
}
そしてもちろんここでは、レデューサーはアプリの状態全体を受け入れて、担当するスライスのみを返します。繰り返しますが、これは単なる関数であり、好きなようにカスタマイズできます。それについてもっと読むことができます こちら