Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

罠 エラーになったときisLoadingがtrueのまま エラーコンポネントじゃなくLoadingが表示 されてしまう postがヌルに要注意。 Can not read property ‘content’ of null

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

さらにフラグ追加

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

遷移図を定義する

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

React に導入! useMachine

Slide 34

Slide 34 text

React に導入!

Slide 35

Slide 35 text

No content

Slide 36

Slide 36 text

シンプルになった!

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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