いまさらuseCallbackを理解したい

reactを触っているとよくわからんhooksランキング上位に入ると思います。
なので今更ですが復習してみましょう。
子コンポーネントの不要な再レンダリングを防ぐ
そんな感じのhooksです。とはいえ言葉で言われてもよくわからないのでコードで見てみましょう
useCallbackなし
import { useState, memo } from "react";
// 子コンポーネント
const Child = memo(({ onClick }: { onClick: () => void }) => {
console.log("Childコンポーネントがレンダーされました");
return <button onClick={onClick}>子ボタン</button>;
});
export default function App() {
const [count, setCount] = useState(0);
const handleClick = () => console.log("clicked!");
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount((c) => c + 1)}>親ボタン +1</button>
<Child onClick={handleClick} />
</div>
);
}
この状態で子ボタンを押下した時のログは以下のようになります。
Childコンポーネントがレンダーされました
clicked!さらに親ボタンを押下するとどうでしょうか?「Childコンポーネントがレンダーされました」がまた出てきます。
Childコンポーネントがレンダーされました
clicked!
ChildコンポーネントがレンダーされましたuseCallbackあり
import { useState, useCallback, memo } from "react";
// 子コンポーネント
const Child = memo(({ onClick }: { onClick: () => void }) => {
console.log("Childコンポーネントがレンダーされました");
return <button onClick={onClick}>子ボタン</button>;
});
export default function App() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log("clicked!");
}, []);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount((c) => c + 1)}>親ボタン +1</button>
<Child onClick={handleClick} />
</div>
);
}
子ボタンを押下した時のログは以下のようになります。この点まではuseCallbackを使わないのと同じ。
Childコンポーネントがレンダーされました
clicked!しかし、親ボタンを押してもログには何も追加されません。
子コンポーネントが再レンダリングされないということです
Childコンポーネントがレンダーされました
clicked!解説
- 子コンポーネントで毎回同じ関数が生成されるので子コンポーネントが毎回レンダリングされてしまう。
- つまりuseCallbackのあるなしで不要なレンダリングが発生することがある。
- 依存配列が変わらない限り 同じ関数オブジェクトを再利用 できる
- 結果として、子コンポーネントの props が「毎回新しくなった」とは見なされず、
React.memoと組み合わせれば 無駄な再レンダーを防止できる
useCallbackなし
このように、親コンポーネントに更新があると追随して子コンポーネントも再レンダリングがかかる

これをuseCallbackを使うことで、必要な親コンポーネントのみが更新され、子コンポーネントは再レンダリングを行わないようにすることができる。
つまり、不要なレンダリングをせずに画面描画速度の上昇や、パフォーマンスを向上することができます

まとめ
- 子コンポーネントに渡される関数にuseCallbackを使用することでReactは同じ関数を再利用する。よって毎回関数を作り直す必要がなくなり、パフォーマンスが向上
- 不要な再レンダリングがされないため、子コンポーネントに安定性に寄与
- 特に関数をpropsとして渡す場面において有効






















