Reactの関数定義

Why useCallback

通常 vs アロー関数

1
function handleClick() {}
1
const handleClick = () => {}

✅ コンポーネントの再レンダリングごとに関数が新しく生成される

  • 共通のデメリット
  • ただし、エンジンの最適化もあり、ほとんどの場合、関数が再生成されても処理コストはほぼゼロ。

React.memo() を使う場合

1
2
3
4
5
6
7
8
9
10
11
12
const Child = React.memo(({ onClick }) => {
console.log("Child rendered");
return <button onClick={onClick}>Click me</button>;
});

function Parent() {
function handleClick() {
console.log("Clicked!");
}

return <Child onClick={handleClick} />;
}

Parent が再レンダリングされるたびに handleClick() が新しく作られるため、Child に渡される onClick が毎回異なるものとみなされる。

これにより、React.memo() が無駄に再レンダリングされてしまう。

useEffect の依存配列に関数を入れる場合

1
2
3
4
5
6
7
8
9
10
11
function App() {
function handleClick() {
console.log("Clicked!");
}

useEffect(() => {
console.log("Effect runs!");
}, [handleClick]); // `handleClick` が毎回新しくなると、`useEffect` が毎回実行される

return <button onClick={handleClick}>Click me</button>;
}

handleClick は App の再レンダリング時に毎回新しい関数となる。

その結果、useEffect の依存配列に handleClick を含めると毎回実行されてしまう。

useCallback

✅ 関数インスタンスが固定される

✅ React.memo や useEffect の最適化に有効