Open13
React API REFERENCEを読む会
初回ここから
useCallbackに関連して下記(ざっくり)読んだ
エフェクトが頻繁に発火するのを防ぐ
useEffectEventのところ読んでるときにあれ?これがないと諸々無理じゃない?と思ったらuseCallbackの記憶が落ちていた
注意:しかし、関数型の依存値を必要としないようにする方がさらに望ましいでしょう。関数をエフェクトの内部に移動します。
memo の使い道
-
props
の変化がない限り再レンダリング不要なコンポーネント
をmemo化
useMemo の使い道
-
依存配列
に変化がない限り計算結果
をmemo化
useCallbackの使い道
-
memo化したコンポーネントに関数を渡しているとき(ex. memo((xxx)=>return <p>{ xxx() }</p> )
- 関数は毎回違うものと判定されてしまいmemo化した意味がなくなるのでそれを防ぐため
-
useEffect 内で関数を呼び出したいとき
- シンプルに書くと依存配列に関数を設定しなくてはいけなくなり、関数は再レンダリングごとに新たなものが作られる性質上 effect が何度も発火してしまう
- useCallbackで囲うことで関数をmemo化し、これを回避できる(同じ関数であるとuseEffectに認識させる方法)
- useEffect 内で関数を宣言できるのであればこちらのほうが良い(そもそもeffectに関数を依存させない方法)
カスタムフックの最適化
なんだよ〜〜〜全部にする必要が無いって思わせたり全てに適用すべきって言ったり混乱しちゃうじゃないか〜〜〜
カスタムフックが関数を返すときはそれらを useCallback でラップするのが良い
memo と一緒に useMemo, useCallbackが使われる理由 -> memo化したコンポーネントに渡す props が毎度変わる(関数、Objectなど)ならmemo化した意味ないからそれらをmemo化して渡す
明らかに再レンダリング時に遅延を感じたらmemo化でok。やりすぎて問題になることはないらしいけどコードが見にくくなる
useCallback は 「useMemoに関数を指定しているときの簡潔な書き方」
(ここから useContext)
memo を使って再レンダーをスキップする場合でも、子コンポーネントがコンテクストから新しい値を受け取ることによる再レンダーは妨げられません。
useDeferredValue
- 再レンダリング時に(stateなどの)古い値を読み取らせ、それでUIを表示することができるhook
- Suspense に対応するデータソースに対して使用する
- <Suspense>を設定していても古い値でのUI表示中はfallbaackが表示されない
- ユーザイベントなど制御できないタイミングでuseDeferredValueに指定した値が再更新された場合、新しい値での再レンダリングイベントはキャンセルされるので安心
- この挙動はありがたいけどサーバ側負荷などの懸念あり。CloudSearchとかでクエリ叩いて検索結果返しているとかだと料金とか怖い。そういうときはdebounce組み込むことも検討したい。
- 値の遅延とデバウンスやスロットリングとの違いで記載があった。useDeferredValueを優先的に使ったほうがユーザ体験は良いが、リクエスト回数などの懸念があるケースではやはりdebounceなどの使用が有用。組み合わせて使うことも可能。