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

状態管理を楽にする道

Kalan
December 11, 2020
240

 状態管理を楽にする道

React HAKATAの発表資料です

Kalan

December 11, 2020
Tweet

Transcript

  1. 状態管理を楽にする道
    @kalanyei

    View Slide

  2. 自己紹介
    Kalan
    台湾出身
    福岡在住
    Twitter: @kalanyei
    React 開発歴五年

    View Slide

  3. よくあるパータン
    1. まずローディングを出す
    2. useEffectでAPIを呼ぶ
    3. setPost を呼んで状態を更新
    4. 記事を表示する

    View Slide

  4. 問題点
    • エラーの場合、どう対応すべきか?
    • Loading は loading フラグで判断ではなく
    postがヌルかどうかで判断する


    View Slide

  5. フラグを追加!
    isLoading, error を追加
    .catchでエラー処理する

    View Slide


  6. エラーになったときisLoadingがtrueのまま
    エラーコンポネントじゃなくLoadingが表示
    されてしまう

    postがヌルに要注意。
    Can not read property ‘content’ of null

    View Slide

  7. View Slide

  8. 仕様変更なら。。。
    • APIが失敗するときに3回までretryしてね。
    • ユーザーが戻るボタンを押したとき、もしAPIが終わって
    いないならキャンセルしてね。

    View Slide

  9. さらにフラグ追加

    View Slide

  10. View Slide

  11. エラーをリセットする必要がある

    View Slide

  12. 問題点
    • 状態が多くなればなるほど負担がかかる
    • 実装を徹底的に見ないとロジックはわからない
    • 仕様変更があったときにコードを変更する必要がある
    • 変更に応じてバグが出やすくなる
    状態が最初から複雑ではなく
    どんどん複雑になっていく

    View Slide

  13. 状態が最初から複雑ではなく
    どんどん複雑になっていく

    View Slide

  14. 解決案 1 - useReducer
    同じところで複数の状態を変更するとき
    通常、useReducer が useState より好ましいのは、複数の値にまたがる複雑な
    state ロジックがある場合や、前の state に基づいて次の state を決める必要があ
    る場合です。また、useReducer を使えばコールバックの代わりに dispatch を下位
    コンポーネントに渡せるようになるため、複数階層にまたがって更新を発生させ
    るようなコンポーネントではパフォーマンスの最適化にもなります。
    https://ja.reactjs.org/docs/hooks-reference.html#usereducer

    View Slide

  15. View Slide

  16. View Slide

  17. View Slide

  18. View Slide

  19. 改善
    • 何をするのかを明示している(アクションの名前でわかる)
    • 実装はアクションやデータを呼ぶだけ
    • reducerで状態遷移を統一している
    • reduxはみんな使っている(かも)
    reducer や actionを定義するのはちょっと面倒くさいけど。。。

    View Slide

  20. 解決案 2 - flag使わず、statusを使う

    View Slide

  21. フラグの問題点
    • if (!loading && success && !canceled)
    みたいなコードが発生しやすい
    • 新しいフラグを追加すると、状態が2^n個になる
    • 開発者はすべての状態を把握することが不可能になる

    View Slide

  22. View Slide

  23. TypeScriptに優しい
    if (status === 'error') {}

    View Slide

  24. また問題点がある
    • 状態遷移の制御はできない
    • 状態遷移はわからない

    View Slide

  25. ステートマシン
    • 遷移(状態に入る、出るとき行う動作)
    • 状態
    • 終了状態
    image source: wiki

    View Slide

  26. ちょっと似てる?
    • actionは遷移(push, coin)
    • statusは状態(locked, un-locked)

    View Slide

  27. 似てるけど足りないよ
    • 制御はできない。(completed状態になってもloading状態に入る
    事ができる)
    • 開始、終了動作は定義していない

    View Slide

  28. xstate
    https://github.com/davidkpiano/xstate
    • Actions :状態に入る、出るときするべきこと
    • Guards:状態遷移を条件による制御すること
    ステートマシンを扱えるJavaScriptのライブラリ

    View Slide

  29. 状態遷移を可視化する
    ちゃんと目で見えると議論しやすい

    View Slide

  30. 遷移図を定義する

    View Slide

  31. View Slide

  32. https://xstate.js.org/viz/

    View Slide

  33. React に導入!
    useMachine

    View Slide

  34. React に導入!

    View Slide

  35. View Slide

  36. シンプルになった!

    View Slide

  37. まとめ
    • フラグをできるだけ抑える
    • フラグを使わずに、statusを定義する
    (TypeScriptに一緒に使うと更に効果的)
    • useReducerを活用する
    • 状態遷移図を事前に定義する
    • 絵を書く
    • xstateみたいな状態管理ライブラリの導入を検討する

    View Slide

  38. リソース
    • xstate: https://xstate.js.org/
    • xstate visualizer
    • Robust User interface with finite state machines
    • XStateで状態遷移を共通言語にしよう
    • Should I useState or useReducer

    View Slide

  39. ご清聴ありがとうございました!

    View Slide