const fn = useCallback(callback, dependencies)
const handleClick = useCallback((e: React.MouseEvent) => {
// ...
}, [dep]);import { useState, useCallback } from 'react';
// ── 問題: 毎回新しい関数が作られてChildが再レンダーされる ──
// 親が再レンダーするたびに handleClick が新しく作られる
// → React.memo でChildをメモ化しても意味がない
// ✅ useCallback で関数をメモ化 ───────────────────────
function Parent() {
const [count, setCount] = useState(0);
const [text, setText] = useState('');
// useCallback: text が変わらない限り同じ関数を使い回す
// → Child コンポーネントの不要な再レンダーを防げる
const handleClick = useCallback(() => {
console.log('クリック!text:', text);
}, [text]); // text が依存配列に入っているので text が変わると更新
return (
<div>
<input value={text} onChange={e => setText(e.target.value)} />
<button onClick={() => setCount(c => c + 1)}>カウント: {count}</button>
{/* Child は handleClick が変わらない限り再レンダーされない */}
<Child onClick={handleClick} />
</div>
);
}
// React.memo と組み合わせるのが典型パターン
const Child = React.memo(({ onClick }: { onClick: () => void }) => {
console.log('Childレンダー'); // 不要な再レンダーを確認できる
return <button onClick={onClick}>実行</button>;
});useCallbackは memo() と組み合わせて初めて効果が出る。memo なしの子コンポーネントに渡しても意味がない。