複数のReducerが存在する場合に渡されるActionたち
分かりづらいRedux
Reactの「state」管理といえば「Redux」という組みわせが多いのではないだろうか?
自分もこの組み合わせで「Redux」に出会ったが、Reactに比較するとはどうも分かりづらい。 (バカな自分にとっては非常に学習コストが高かった...)
とりあえず使うことはできるが「理解している」のかと言われてしまうと言葉に詰まる。
その中でも、最近疑問に思ったのはReducerとActionの関係。
特にReducerが複数存在し、combineされた後の挙動がどうしてもしっくりこなかった。
「複数Action、複数Reducerが存在するのに発行されたActionはどうやって、自分自身が処理対象となっているReducerを特定しているのだろう?」と。
単一のActionとReducerの関係
1対1となっている場合は、割とすんなり理解できる。Sampleコードとして下記のようなコードが示されることが多い。
特定のTypeをもつActionとそれをハンドリングするReducer。
// Action const sampleAction_A = (arg) => ({ type: 'SAMPLE_ACTION_A', payload: { arg }, error: false }) const sampleAction_B = (arg) => ({ type: 'SAMPLE_ACTION_B', payload: { arg }, error: false }) // Reducer function sampleA_Reducer(state, action) { switch(action.type) { case 'SAMPLE_ACTION_A': return { node: action.payload.arg } case 'SAMPLE_ACTION_B': return { node: action.payload.arg } default: return state } }
この場合はActionをハンドリングするReducerが一つであるため、発行されたActionが渡されるReducerが「sampleA_Reducer」だと分かる。
よく書籍で説明される「指定のTypeをもつAction発行され、Reducerによって状態が変化します。」という説明が理解できる。
しかし、ReducerとActionが増えてしまうと上記の説明だけでは、理解したと私的には言い難い...
複数のActionとReducerの関係
さて本題に入るが、結論から言うと「ActionはReducerを特定などしていない。」が正解だった。
発行されたActionはcombineされたすべてのReducerに対して渡されていく。
疑問に思ったのは下記のような場合。
通常Actionに依存関係がなく、ハンドリングとしても分けられる場合には、Actionとそれに対応するReducerを分けて作成する。
// Action const actionA = (args) => ({ type: 'A_ACTION', payload: { args }, error: false }) const actionB = (args) => ({ type: 'B_ACTION', payload: { args }, error: false }) // Reducer export const actionA_Reducer = (state, action) => { switch(action.type) { case 'A_ACTION': return { node: action.payload.args } default: return state } } export const actionB_Reducer = (state, action) => { switch(action.type) { case 'B_ACTION': return { node: action.payload.args } default: return state } }
そしてこれらのReducerをcombineしてRootReducerを作成する。
// RootReducerを作成する const rootReducer = combineReducers({ actionA_Reducer, actionB_Reducer })
このような場合に「A_ACTION」が発行されると、storeに紐づいているすべてのReducerに対して、Actionが渡されていく。
これはVS Codeなどを使用してDebugすると簡単に確かめることができる。
変わらないことも重要
「Reducerを特定しない。」「すべてのReducerに渡される」というのであれば適切に対象Actionを処理することも大切だが、不用意な変化をさせないということも重要。
何冊か「React-Redux」に関する書籍は読んだが、ここら辺は自分が覚えている限りでは詳細な記載がなかったので、やっぱり疑問に思ったことは時間を作ってでも調べた方がいいね。