【ISSUE】Reduxのstateが更新されない

0

2024年12月23日 22:38

概要

React(Redux)のstate更新が想定通りにいかずに半べそかいてる過去の自分に向けた手紙

解決できること

「stateが更新されないToT」という状態から脱出できる。

version

Screen Shot 2021-12-26 at 15.46.30.png

背景

開発メンバーから「useSelectorで取得してる値が古いままなんですが…」と相談を受けました。
そして、思い出しました。自分もReact触り始めの時に同じ症状で苦しんだことを。

自分もちゃんと原因確かめないまま進んでいたなと思い出して、備忘録も兼ねて書いておきます。
Redux Toolkitをsampleに進めていきます。

やりたいこと

  • 関数A というbutton押下でAの値が+5される。押した回数増えていく
  • 関数B というbutton押下でBの値にAの値を加える

(例) 関数B を実行すると

state \ 回数1234
A5101520
B5153050

という振る舞いを実装したい。

元にしたcode sandbox

https://codesandbox.io/s/keen-sunset-gzhb5

製作者に感謝m_ _m
ディレクトリ構造とかは今回簡易的な試すだけなのでご了承下さい。

①Aのbuttonを実装する

Redux(Toolkit)知ってるよって人は飛ばしてください。

  • hogeSlice というfileにreducerやら、stateが格納されていてexportしてます
  • stateを使うときは useSelector で参照する
  • exportした関数は dispatch(hoge(payload)) で実行する
  • Reduxと比べて非同期処理がシンプルに書ける

この辺りが特徴かと思います。

img

img

https://codesandbox.io/s/redux-toolkit-step1-h3s2v

②Bのbuttonを実装する

reduxtoolkit.gif

はい。不具合が出てますね。
みた感じはAの更新される前の値がBに加えられているように見えます。

img

img

state \ 回数1234
A5101520
B5153050

ではなく、

state \ 回数1234
A5101520
B051535

となっています。

https://codesandbox.io/s/redux-toolkit-step2-v2too

試したこと

  • 拡張機能を使ってstateを追いかける
  • たくさんconsole.log(state)して中身を見にいく
  • useSelectorの公式を読む
  • 非同期的なことかと思い、dispatchにawaitつけたり、reducerの処理を非同期にしてみる

この辺りを試していくうちに「よくわからん」となることが多いのかなと思います。

想定通りにならない原因

https://numb86-tech.hatenablog.com/entry/2020/03/24/114624#:~:text=useState%20%E3%82%84%20useReducer%20%E3%81%A8%E7%B5%84%E3%81%BF%E5%90%88%E3%82%8F%E3%81%9B%E3%82%8B

useState や useReducer と組み合わせる

useStateやuseReducerによる更新とdispatchによる更新を、一度のイベントのなかで同期的に行った場合、再レンダリングは一度だけ行われる。

React書いてると忘れがちになるのですが、そもそもcomponentって関数なので、内包されてる値は実行時に決まります = レンダリングのタイミング。
この辺の感覚を再認識して修正していきます。

改修方法① store.getState()を使う

img

const res = store.getState();
dispatch(plusB(res.counter.valueA));

一番最初に思いついた方法。
ただ感覚的にはあまりイケてない気がする。もうちょっと他の人のコード見てみたいなぁ…
storeを至るところで呼ぶというのがあまり良くない気がする(気がするだけかもしれない)

改修方法② reducerのロジックを変更する

img

img

①よりはまだ良いと思っています。storeの中の値は更新されているので振る舞い通りに実装できる。
ユースケース次第では冗長的になりすぎる気もする。

改修方法③ createAsyncThunkを使う

今回のケースでは関係ありませんが、実際のケースではこういった簡易なstate更新は少なく、
API叩いてデータとってきて…ということが多くなると思うので、非同期実装が必要なタイミングもあるので備忘録的な意味で書いておきます。

上記①〜③を書いたsandbox

https://codesandbox.io/s/redux-toolkit-step3-uelqp

Redux Toolkit公式

https://redux-toolkit.js.org/api/createAsyncThunk

あとがき

そろそろRecoilやらSWRも触っていきたいお年頃…

参考にさせて頂いた記事

https://zenn.dev/syu/articles/3c4aa813b57b8c

https://numb86-tech.hatenablog.com/entry/2020/03/24/114624
[cv:issue_marketplace_engineer]

0

診断を受けるとあなたの現在の業務委託単価を算出します。今後副業やフリーランスで単価を交渉する際の参考になります。また次の単価レンジに到達するためのヒントも確認できます。