useCallback
以下は同じ
code:ts
useCallback(fn, deps);
useMemo(()=>fn, deps);
再描画時にdepsに前回と比べて変更があるとコールバックするfunctionを再編成する
考え方としては、fnの中で使う値を、depsに指定しておけばいい
ないとバグが起きる可能性が上がる
逆に「第二引数を使わない」ということはまずありえない
無意味だから。型エラーが出るので気付くはず
空配列はありうる
例
code:ts
// returnFuncは関数になる
const returnFunc = useCallback(fn, deps)
depsに変更があるとそのureturnFuncが新しく生成される
FC内で定義された関数は、FCが再レンダリングされるたびに新しいものになる
そもそもの話
子にその関数を渡すと親が再レンダリングされるたびに子も無駄に再レンダリングされる
code:ts
const Parent = (props) => { // このpropsが変わるたびにParentは再レンダリングされる(普通に)
const f = () => {} // そのたびにこの関数は新しく作られる
return (
<Child onClick={f} /> // fが新しくなるので無駄にChildが再レンダリングされる(React.memoを使っていても)
)
}
これを防ぐためにuseCallbackを使う
code:ts
const f = useCallback(() => {}, なんか) class時代の関数をインラインで書くな問題がFCではもっと顕著に起こる
ない
React guarantees that setState function identity is stable and won’t change on re-renders. This is why it’s safe to omit from the useEffect or useCallback dependency list. ref depsにdispatchを入れる意味はあるか?
objectなので、毎回生成されるので、無意味になる
JSON.stringifyする?
ロジックに依っては、xs.lengthでも良いかも
ミスったらめちゃくちゃわかりづらいバグになりそうだけど
useCallbackに第3引数を設け、自作のcompare関数を書いて比較する
こんなhooksを書いたとき
code:ts
const usePageNavigation = <T>() => {
// ページ遷移時は、先頭に追加する
const push = useCallback((stack: T) => {
}, []);
const pop = () => {
setStacks((...rest) => rest);
} // useCallback使う?使うならdepsはなに?
const reset = useCallback(() => {
setStacks([]);
}, []);
return {
push,
pop,
reset
};
};
popのdepsに入れるべき値はなにか?
stacks?
useStateで作られたstateって変化がない場合って参照は同じものなのか?
同じものなのであれば、stacksでいいし、同じものでないならstacksと書いても無意味
そのstateが全く変わってなかったら参照は同じ
でも今回のケースではmethodを呼ぶと絶対にstateが変わるようなhooksなのでやっぱ意味ないな
stacks[0]?
いや、意味ないなたぶん
useCallbackを使う意味がない気がする
引数を取っていない以上、stacksが変わるたびに再生成しないと動かなくなる
で、stacksは毎回変わるので、意味ない
本当にここをどうにかしたいなら、引数に取るべし
でも、それはinterface的に微妙なので却下
配列の中の一要素を見るとか
[arr[0].hoge]
適当に選択するのではなく、viewの更新にふさわしいkeyを指定する
頻繁に更新するべきか、そうでないか、などを鑑みながら
asyncを入れることある?
副作用?