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

状態管理を楽にする道

Kalan
December 11, 2020
260

 状態管理を楽にする道

React HAKATAの発表資料です

Kalan

December 11, 2020
Tweet

Transcript

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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


    View full-size slide

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

    View full-size slide


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

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

    View full-size slide

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

    View full-size slide

  8. さらにフラグ追加

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  23. 遷移図を定義する

    View full-size slide

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

    View full-size slide

  25. React に導入!
    useMachine

    View full-size slide

  26. React に導入!

    View full-size slide

  27. シンプルになった!

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide