LoginSignup
2
2

More than 5 years have passed since last update.

Reduxで、reducer内でstateを書き換えると怒られる話

Posted at

初めに

こんな感じでreduxのreducerを書いたら何故かexceptionが吐かれてとても悩んだ。

export default (state: State = INITIAL_STATE, action: ActionType): State => {
  switch (action.type) {
    case MY_ACTION_NAME: {
      const current = state.handlingData;
      action.dataArray.forEach((d) => {
        current[d.key] = d.data;
      });
      return {
        ...state,
        handlingData: current,
      };
    }
    default:
      return state;
  }
};

エラーメッセージはこんな感じ ↓

YellowBox.js:78 Possible Unhandled Promise Rejection (id: 0):
Invariant Violation: A state mutation was detected inside a dispatch, in the path:  (state名)

原因

realmを使っていたり非同期にしていたりするせいで何かよくわからないところで変なエラーが起きているんじゃないか、とか余計なことを考えて的外れな調査をしてしまい時間がかかったが、何てことはない。
メッセージ通り、以下のようにreducer内でstateを書き換えていたのが原因だった。

      const current = state.handlingData;
      action.dataArray.forEach((d) => {
        current[d.key] = d.data; // ← currentがstateの一部なのでこれで書き換わっている
      });

ちなみに、console内に出力されるエラーメッセージに以下のリンクが貼られていたお陰で気付くことができた。

対策

上記の部分を以下のように書き換えたら直った。

      const current = { ...state.handlingData };
      action.dataArray.forEach((d) => {
        current[d.key] = d.data;
      });

終わりに

  • 気を付けよう。
  • 公式リファレンスは役に立つ。
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2