useMemoとuseCallbackの使いどころ
#React
基本的には全ての値に書け、react-hooks/exhaustive-deps を常に "error" レベルで有効にせよ、と言っている
依存配列を制御したいと考えるとき、それは道具の使い方を正すことを諦めている
合わせて読みたい:https://beta.reactjs.org/learn/removing-effect-dependencies#to-change-the-dependencies-change-the-code
合わせて読みたい:https://blog.uhy.ooo/entry/2021-02-23/usecallback-custom-hooks/
合わせて読みたい: #Reactに関係あるものだけをカスタムフックにする
そもそもなんだっけ
この説明はしない
これらを使うだけでは意外と何も起こらない
render時の関数の生成は減らせない。 useCallback(() => {}, []) と書いただけで関数は作られている
新しいものを使う必要がないときに同じものが返ってくるだけ
useMemo/useEffectでも同じことが起きている。実行されてないだけ
renderの回数は、値を渡す先のコンポーネントが React.memo によりメモ化されていないと減らせない
classベースのときの PureComponent 相当動作がこれ
Reactでrenderごとに参照が安定しているとうれしいこと
値を受け取る側のコンポーネントが考慮していることの影響を受けられる
React.memo でコンポーネント自体がメモ化されているときに、render自体を省略できる
useEffect で必要ない副作用を省略できる
useMemo で高コスト計算を省略できる
値を使う側でuseMemo/useCallbackしていても、依存配列に入ってくる値がメモ化されていなかったら毎回別の参照になる
呼び出す側の記述で、道具側で丁寧に書いているものを無駄にしてしまう
これらをうけて、私はこうしている
カスタムフックをかくとき
返す値は全てメモ化する
カスタムフック内で作る値は基本的にメモ化する
カスタムフックに渡すものはメモ化する
useRefに入れるだけのものはやらなくていい、とかはわかるよね
コンポーネントをかくとき
新規に作って子に渡す値は全てメモ化する
親からもらって子にパススルーしている値は何もしない
DOM要素のイベントハンドラーに直ちに渡す関数は実はメモ化しなくても良いが、区別がつかなかったりリファクタリングで前提が変わりやすいのでメモ化する
道具側も全部書かないようにしたら全部書かなくてよくない?
それなり規模で問題になってから必要なところに書いていくのはかなり苦痛なので、それでもいいなら
そもそも全く書かなくても大抵の場合は困らない、というのがReactに関わっている人のコメントにある
codemodみたいなもので全部自動追記できるならそのスタイルもありかもね
全くメモ化されてなくてuseEffect走りまくり、再計算が走りまくりよりは、メモ化して依存配列をメンテするコストの方が安い気がします
往々にして開発者のマシンは強いので問題が起きていても気付きづらいです。CPUスロットリングを1日どれくらい使っていますか? たぶんゼロですよね?
useRefに最新の関数を保持するハック、useEventみたいなもの
これでもいいです。子やカスタムフックに値を渡すときに参照が安定することの話をしています