React基礎|useCallbackとは?なぜ使用するか解説
useCallbackは何のために使用するのか解説
6/11/2025
useCallbackとは?
関数をメモ化するのに使用する。
親コンポーネントから子コンポーネントに関数を渡している場合、親コンポーネントがレンダリングされると、渡している関数も更新されるため、関数を受け取っている子コンポーネントもレンダリングされてしまう。
✅useCallback の主な目的
関数参照の変更によって子コンポーネントの再レンダリングが起きないようにする。
📝useCallbackを使用する場合としない場合の比較
src/
├── components/
│ └── IncrementButton.jsx
├── hooks/
│ └── useCounter.js
└── App.jsx- 親コンポーネント(App,js)に子コンポーネント(IncrementButton.jsx)を読み込んで、クリック時の関数をpropsで渡す。
- 関数はカスタムフック内(useCounter.js)で作成し、親コンポーネント(App,js)に読み込む。(カスタムフックでなく、親コンポーネントに直接関数を記載しても同じ)
❌useCallback( メモ化)なし:不要な再レンダリングが発生する
📁カスタムフック|hooks/useCounter.js
import { useState } from "react";
const useCounter = () => {
const [count, setCount] = useState(0);
const increment = () => {
setCount((prev) => prev + 1);
};
return { count, increment };
};
export default useCounter;📁ボタンコンポーネント|components/IncrementButton.jsx
import React from "react";
const IncrementButton = React.memo(({ onClick }) => {
console.log("Button rendered");
return <button onClick={onClick}>+1</button>;
});
export default IncrementButton;📝React.memo
📁親コンポーネント|App.jsx
import React from "react";
import useCounter from "./hooks/useCounter";
import IncrementButton from "./components/IncrementButton";
const App = () => {
const { count, increment } = useCounter();
return (
<div>
<h1>Count: {count}</h1>
<IncrementButton onClick={increment} />
</div>
);
};
export default App;- カスタムフックから、結果を表示させる
countと関数incrementを取得 - ボタンコンポーネントに関数を
increment渡す。
⚡️結果:ボタンをクリックするたびにボタンコンポーネントがレンダリングされる
ボタンをクリックすると、count の状態が変わる。その際に再レンダリングされる。
そしてのたびに increment 関数の参照も変わる → ボタンコンポーネントもレンダリングされ、コンソールにButton rendered が毎回表示される。
❌親コンポーネントの値だけ変わればいいのに、変化がない子コンポーネントも再レンダリングする必要はない。
✅ useCallback(メモ化)あり:不要な再レンダリングを防ぐ
📁カスタムフック|hooks/useCounter.js
import { useState, useCallback } from "react";
const useCounter = () => {
const [count, setCount] = useState(0);
const increment = useCallback(() => {
setCount((prev) => prev + 1);
}, []);
return { count, increment };
};
export default useCounter;increment関数をuseCallbackでメモ化- 他のコンポーネントへの変更はなし
⚡️結果:increment 関数はメモ化されていて参照が変わらない → Button rendered は初回のみ表示される
親コンポーネントの初回レンダリングで子コンポーネントもレンダリングされる。それ以降は親コンポーネントのcountの値が変わっても、関数はメモ化されているので再レンダリングされない。→子コンポーネント(ボタン)の無駄なレンダリングを防ぐことができる。