Upgrade to Pro — share decks privately, control downloads, hide ads and more …

propsのバケツリレー対策でGlobal_Stateを使うその前に

taro
January 18, 2023

 propsのバケツリレー対策でGlobal_Stateを使うその前に

こちらのイベントで使用した登壇資料です!
https://thecoo.connpass.com/event/269188/

taro

January 18, 2023
Tweet

More Decks by taro

Other Decks in Technology

Transcript

  1. propsのバケツリレー対策で
    Global Stateを使うその前に…
    フロントエンドLT新年会 2023.1.18
    taro(@taroro_tarotaro)

    View full-size slide

  2. 自己紹介
    ● taro( @taroro_tarotaro)
    ● シェルフィー株式会社で建設SaaSを作ってます!(2020.11〜)
    ● React, TypeScript, Server Side Kotlin
    ※Reactしか触ったことがないため、Reactをベースとした話になります🙏

    View full-size slide

  3. はじめに

    View full-size slide

  4. はじめに
    昨今よく言われるReactのstateの分類
    1. Server Data Cache
    2. Global State: 1を除くページをまたいで保持し続ける必要のあるstate
    3. Local State: ページをまたいで保持する必要のないstate
    https://zenn.dev/yoshiko/articles/607ec0c9b0408d

    View full-size slide

  5. はじめに
    昨今よく言われるReactのstateの分類
    1. Server Data Cache
    ○ TanStack Query, swr, etc.
    2. Global State: 1を除くページをまたいで保持し続ける必要のあるstate
    ○ useContext, Recoil, Jotai, Redux, Zustand, etc.
    3. Local State: ページをまたいで保持する必要のないstate
    ○ useState, etc.

    View full-size slide

  6. はじめに
    昨今よく言われるReactのstateの分類
    1. Server Data Cache
    ○ TanStack Query, swr, etc.
    2. Global State: 1を除くページをまたいで保持し続ける必要のあるstate
    ○ useContext, Recoil, Jotai, Redux, Zustand, etc.
    3. Local State: ページをまたいで保持する必要のないstate
    ○ useState, etc.
    💡Local Stateを実装的都合でGlobal Stateの管理手法を使う時の話

    View full-size slide

  7. はじめに
    Local Stateを実装的都合でGlobal Stateの手段で管理する時の話
    ● どんなケースか
    ● その場合のむずかしさ
    ● ケース別にLocal Stateでうまくやる方法
    ※変更頻度が多く複数人で触るようなComponentを前提としています🙇

    View full-size slide

  8. 実装的にGlobal Stateで
    管理したくなるケース

    View full-size slide

  9. 実装的にGlobal Stateで管理したくなるケース
    ● 子、孫Component間でstateを共有したい
    ● propsのバケツリレー(props drilling)を避けたい
    ● 子Component内のstateを親Componentから制御したい
    など
    →Global Stateで管理してもよいがむずかしさがある

    View full-size slide

  10. Global Stateで管理する時の
    むずかしさ

    View full-size slide

  11. Global Stateで管理する時のむずかしさ
    ● スコープが広がる
    ○ まぁGlobalだからね(Atoms系だと違うかも)
    ● データフローが見えづらくなる
    ○ 子Componentのpropから消えるため
    ● ライフタイムが伸びる
    ○ これの考慮が結構忘れがち
    ○ クリーンアップ忘れて変更前のstateがチラっと見えちゃう🫣

    View full-size slide

  12. Global Stateで管理する時のむずかしさ
    ● スコープが広がる
    ○ まぁGlobalだからね(Atoms系だと違うかも)
    ● データフローが見えづらくなる
    ○ 子Componentのpropから消えるため
    ● ライフタイムが伸びる
    ○ これの考慮が結構忘れがち
    ○ クリーンアップ忘れて変更前のstateがチラっと見えちゃう🫣
    →影響範囲の把握コストが増える

    View full-size slide

  13. Global Stateで管理する時のむずかしさ
    ● スコープが広がる
    ○ まぁGlobalだからね(Atoms系だと違うかも)
    ● データフローが見えづらくなる
    ○ 子Componentのpropから消えるため
    ● ライフタイムが伸びる
    ○ これの考慮が結構忘れがち
    ○ クリーンアップ忘れて変更前のstateがチラっと見えちゃう🫣
    →影響範囲の把握コストが増える
    →僕はLocal Stateでがんばる派でその方法を紹介していく

    View full-size slide

  14. Local Stateで
    うまくやる方法

    View full-size slide

  15. Local Stateでうまくやる方法
    実装的にGlobal Stateで管理したくなるケース
    ● 子、孫Component間でstateを共有したい
    ● propsのバケツリレー(props drilling)を避けたい
    ● 子Component内のstateを親Componentから制御したい

    View full-size slide

  16. Local Stateでうまくやる方法
    実装的にGlobal Stateで管理したくなるケース
    ● 子、孫Component間でstateを共有したい
    ● propsのバケツリレー(props drilling)を避けたい
    ● 子Component内のstateを親Componentから制御したい

    View full-size slide

  17. Local Stateでうまくやる方法
    ①まずは基本のLifting State Up
    「当たり前だろ!」と言われるかもしれないが、
    親に持ち上げてstateの持ち方を変えるだけで意外と解決したりする。

    View full-size slide

  18. Local Stateでうまくやる方法
    ①まずは基本のLifting State Up
    「当たり前だろ!」と言われるかもしれないが、
    親に持ち上げてstateの持ち方を変えるだけで意外と解決したりする。
    →「いやいやそうするとpropsをバケツリレーしないといけないんよ…」

    View full-size slide

  19. Local Stateでうまくやる方法
    実装的にGlobal Stateで管理したくなるケース
    ● 子、孫Component間でstateを共有したい
    ● propsのバケツリレー(props drilling)を避けたい
    ● 子Component内のstateを親Componentから制御したい

    View full-size slide

  20. Local Stateでうまくやる方法
    ②propを渡すこと自体はそんなに悪いことではない
    ● むしろ依存関係があるから、依存関係がわかるように書いている
    ● ただ個数が多かったり、バケツリレーを繰り返してたら疑うのは大切

    View full-size slide

  21. Local Stateでうまくやる方法
    ③そもそもそんなにComponentをネストさせる必要があるのか?

    View full-size slide

  22. Local Stateでうまくやる方法
    ③そもそもそんなにComponentをネストさせる必要があるのか?
    ※変更頻度が多く複数人で触るようなComponentが前提
    ● ロジックやstateはCustom Hookで責任ごとに分ける
    ● 機能に依存しない小さな汎用Componentを作る
    ● 機能のComponentはそれらを組み合わせ機能内でのネストは最小限にする
    ○ Viewの全体像がわかりやすい
    ○ 不要なインターフェースが生まれず、柔軟性が保たれる

    View full-size slide

  23. Local Stateでうまくやる方法
    ④Composition: childrenを使う
    propが減って変更に強くなり、また状態の依存関係がわかりやすくなる

    View full-size slide

  24. Local Stateでうまくやる方法
    ⑤Composition: render props使う
    親Componentの肥大化を防ぎたい時におすすめ(初見の難しさが少し上がる)

    View full-size slide

  25. Local Stateでうまくやる方法
    実装的にGlobal Stateで管理したくなるケース
    ● 子、孫Component間でstateを共有したい
    ● propsのバケツリレー(props drilling)を避けたい
    ● 子Component内のstateを親Componentから制御したい

    View full-size slide

  26. Local Stateでうまくやる方法
    ①やっぱりまずは基本のLifting State Up
    そもそも親から制御したいという要求の時点で危険な臭いがする…
    (ただ実際やりたいケースもあるので紹介していく)

    View full-size slide

  27. Local Stateでうまくやる方法
    ⑥Component自体を初期化する
    ● 親から制御したい多くのケースはstateの初期化
    ● Componentに動的なkeyを渡すとkeyごとにComponentを作り直してくれる

    View full-size slide

  28. Local Stateでうまくやる方法
    ⑥Component自体を初期化する
    ● 親から制御したい多くのケースはstateの初期化
    ● Componentに動的なkeyを渡すとkeyごとにComponentを作り直してくれる
    「〇〇から◆◆に変わったら、△△する」のではなく、
    「〇〇の時は♡♡、◆◆の時は△△する」と考えるのが大切(宣言的)

    View full-size slide

  29. Local Stateでうまくやる方法
    ⑥Component自体を初期化する
    ● 親から制御したい多くのケースはstateの初期化
    ● Componentに動的なkeyを渡すとkeyごとにComponentを作り直してくれる
    →「いやいやComponentをUnmountさせるのはUX的にやりたくない」
    →「特定のstateだけ初期化(制御)したい」

    View full-size slide

  30. Local Stateでうまくやる方法
    ⑦propとstateの値からsetStateする

    View full-size slide

  31. Local Stateでうまくやる方法
    ⑦propとstateの値からsetStateする
    ● 状態の性質として正しい姿を宣言する
    ● useEffectは不要( 使うと前のstateで一度DOMにcommitされてしまう)
    「〇〇から◆◆に変わったら、△△する」のではなく、
    「〇〇の時は♡♡、◆◆の時は△△する」と考えるのが大切(宣言的)

    View full-size slide

  32. Local Stateでうまくやる方法
    ⑧前レンダリング時のstateやpropの値を保持するstateを使う
    ● これは正直あんまりやりたくない
    ● ここまでくるともしかしたらGlobal Stateを使う方がシンプルかもしれない

    View full-size slide

  33. Local Stateでうまくやる方法
    ①まずは基本のLifting State Up
    ②propを渡すこと自体はそんなに悪いことではない
    ③そもそもそんなにComponentをネストさせる必要があるのか考える
    ④Composition: childrenを使う
    ⑤Composition: render propsを使う
    ⑥Component自体を初期化する
    ⑦propとstateの値からsetStateする
    ⑧前レンダリング時のstateやpropの値を保持するstateを使う

    View full-size slide

  34. まとめ
    ● 実装都合でGlobal Stateを使う時はむずかしさの考慮を忘れずに
    ○ 制約がない・自由の裏には何があるのか
    ● 設計を見直すとLocal Stateでも意外といける
    ○ Hackではなく全て公式ドキュメントの方法

    View full-size slide

  35. 積極採用中です!!

    採用情報はこちら! https://hello.shelfy.co.jp 


    View full-size slide