React+Reduxのパターンで開発しているとアクション名の衝突を避けるために管理が煩雑になってきます。
例えば、ある機能でINCREMENT
というアクション名をすでに使用している場合、他の機能で同じような振る舞いのアクションを定義する場合はINCREMENT
という命名を避けなければなりません。
これは、アクション名が衝突するとそれぞれに定義されたreducerが発火してしまい意図しない動作を引き起こしてしまうためです。
そのため、XXX/INCREMENT
、ZZZ/INCREMENT
のように機能ごとのprefixをつけてアクション名の衝突を避ける工夫が必要になります。
redux-actionsを使ってアクション名の衝突を避ける方法
アクションの定義にはredux-actionsというライブラリを使用しているケースが多いかと思います。
redux-actionsを使用することで上記のようなアクション名の衝突を避けるような命名をすることが出来ます。
const { increment, decrement } = createActions( 'INCREMENT', 'DECREMENT', { prefix: 'XXX' }, );
createActionsのオプションにprefixを設定することで、アクション名がXXX/INCREMENT
、XXX/DECREMENT
という命名に変更されます。
同様にreducer側で使用するhandleActionsメソッドにおいてもprefixを指定する必要があります。
export default handleActions({ [actionTypes.INCREMENT]: (prevState, action) => { return { ...prevState, count: count + 1, }; }, [actionTypes.DECREMENT]: (prevState, action) => { return { ...prevState, count: count - 1, }; }, }, defaultState, { prefix: XXX });
また、注意点としてredux-sagaを使用している場合、takeEvery
等でアクション名のパターンマッチングをしていますので、そこの考慮も必要になります。
redux-actionsとは別のライブラリですので、仕様のギャップは吸収しなければなりません。
export default function* () { yield takeEvery(`XXX/${actionTypes.INCREMENT}`), increment); yield takeEvery(`XXX/${actionTypes.DECREMENT}`), decrement); }