【ISSUE】Reduxのstateが更新されない
2024年12月23日 22:38
React(Redux)のstate更新が想定通りにいかずに半べそかいてる過去の自分に向けた手紙
「stateが更新されないToT」という状態から脱出できる。
開発メンバーから「useSelectorで取得してる値が古いままなんですが…」と相談を受けました。
そして、思い出しました。自分もReact触り始めの時に同じ症状で苦しんだことを。
自分もちゃんと原因確かめないまま進んでいたなと思い出して、備忘録も兼ねて書いておきます。
Redux Toolkitをsampleに進めていきます。
関数A
というbutton押下でAの値が+5される。押した回数増えていく関数B
というbutton押下でBの値にAの値を加える(例) 関数B
を実行すると
state \ 回数 | 1 | 2 | 3 | 4 |
---|---|---|---|---|
A | 5 | 10 | 15 | 20 |
B | 5 | 15 | 30 | 50 |
という振る舞いを実装したい。
https://codesandbox.io/s/keen-sunset-gzhb5
製作者に感謝m_ _m
ディレクトリ構造とかは今回簡易的な試すだけなのでご了承下さい。
Redux(Toolkit)知ってるよって人は飛ばしてください。
hogeSlice
というfileにreducerやら、stateが格納されていてexportしてますuseSelector
で参照するdispatch(hoge(payload))
で実行するこの辺りが特徴かと思います。
https://codesandbox.io/s/redux-toolkit-step1-h3s2v
はい。不具合が出てますね。
みた感じはAの更新される前の値がBに加えられているように見えます。
state \ 回数 | 1 | 2 | 3 | 4 |
---|---|---|---|---|
A | 5 | 10 | 15 | 20 |
B | 5 | 15 | 30 | 50 |
ではなく、
state \ 回数 | 1 | 2 | 3 | 4 |
---|---|---|---|---|
A | 5 | 10 | 15 | 20 |
B | 0 | 5 | 15 | 35 |
となっています。
https://codesandbox.io/s/redux-toolkit-step2-v2too
この辺りを試していくうちに「よくわからん」となることが多いのかなと思います。
useState や useReducer と組み合わせる
useStateやuseReducerによる更新とdispatchによる更新を、一度のイベントのなかで同期的に行った場合、再レンダリングは一度だけ行われる。
React書いてると忘れがちになるのですが、そもそもcomponentって関数なので、内包されてる値は実行時に決まります = レンダリングのタイミング。
この辺の感覚を再認識して修正していきます。
const res = store.getState();
dispatch(plusB(res.counter.valueA));
一番最初に思いついた方法。
ただ感覚的にはあまりイケてない気がする。もうちょっと他の人のコード見てみたいなぁ…
storeを至るところで呼ぶというのがあまり良くない気がする(気がするだけかもしれない)
①よりはまだ良いと思っています。storeの中の値は更新されているので振る舞い通りに実装できる。
ユースケース次第では冗長的になりすぎる気もする。
今回のケースでは関係ありませんが、実際のケースではこういった簡易な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]
診断を受けるとあなたの現在の業務委託単価を算出します。今後副業やフリーランスで単価を交渉する際の参考になります。また次の単価レンジに到達するためのヒントも確認できます。