useCallback
useMemoの関数版
以下は同じ
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ではもっと顕著に起こる
#WIP
Reactでのメモ化の方針
depsにuseStateのsetState系の関数を入れる意味はあるか?
ない
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の比較は===
#??
depsにdispatchを入れる意味はあるか?
depsに入れたいものが配列の場合はどう書くべきか?
objectなので、毎回生成されるので、無意味になる
JSON.stringifyする?
ロジックに依っては、xs.lengthでも良いかも
ミスったらめちゃくちゃわかりづらいバグになりそうだけど
https://github.com/facebook/react/issues/14476#issuecomment-471199055
https://github.com/facebook/react/issues/14476#issuecomment-595569382
use-custom-compareを使う
https://github.com/kotarella1110/use-custom-compare
このissueの問題提起をlibraryとして実装したもの
useCallbackに第3引数を設け、自作のcompare関数を書いて比較する
こんなhooksを書いたとき
code:ts
const usePageNavigation = <T>() => {
const stacks, setStacks = useState<T[]>([]);
// ページ遷移時は、先頭に追加する
const push = useCallback((stack: T) => {
setStacks(s => stack, ...s);
}, []);
const pop = () => {
setStacks((...rest) => rest);
return stacks1;
} // 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を指定する
頻繁に更新するべきか、そうでないか、などを鑑みながら
https://tech-1natsu.hatenablog.com/entry/2019/02/14/214816
Custom Hooksが返す関数はuseCallbackを使う
https://blog.uhy.ooo/entry/2021-02-23/usecallback-custom-hooks/
asyncを入れることある?
副作用?
https://qiita.com/uhyo/items/246fb1f30acfeb7699da#usecallback
https://qiita.com/jonakp/items/0db6fb9e75edcec875b2
https://blog.uhy.ooo/entry/2021-02-23/usecallback-custom-hooks/
https://github.com/facebook/react/issues/16956