usememoとuseCallbackについて
useMemo と useCallback は、Reactでパフォーマンス最適化を行うためのフック(Hook)です。
前提:Reactの再レンダーの仕組み
Reactは、親コンポーネントが再レンダーすると子コンポーネントも再レンダーします。
そのとき、
■関数 (() => {...})
■オブジェクト ({})
などは毎回新しく作られる別のものと見なされます。
そのため、子コンポーネントが React.memo でラップされていても、
props に「新しい関数」や「新しいオブジェクト」が渡されると
無駄に再レンダーされてしまうことがあります。
useMemoとは?
⇒ 「計算結果をメモ(記憶)しておく」フック
const memoizedValue = useMemo(() => {
return heavyCalculation(a, b);
}, [a, b]);
■「a」 または「 b 」が変わったときだけ再計算。
■それ以外は前回の結果を再利用。
使う場面
■計算コストが高い処理を繰り返し呼びたくないとき
■オブジェクトや配列を安定させたいとき(useEffectやReact.memoの依存関係を安定化)
サンプル(useMemo)
import React, { useMemo, useState } from "react";
export const UseMemoExample = () => {
const [count, setCount] = useState(0);
const [text, setText] = useState("");
// 重い計算(実際は単純化してます)
const heavyResult = useMemo(() => {
console.log("重い計算を実行中…");
return count * 2;
}, [count]); // ← countが変わったときだけ計算される!
return (
<div>
<h2>useMemoの例</h2>
<p>結果: {heavyResult}</p>
<button onClick={() => setCount((c) => c + 1)}>+1</button>
<input
value={text}
onChange={(e) => setText(e.target.value)}
placeholder="テキスト入力"
/>
</div>
);
};
useCallbackとは?
☞「関数をメモ(記憶)しておく」フック
const memoizedFn = useCallback(() => {
doSomething(a, b);
}, [a, b]);
■「a 」や「 b 」が変わったときだけ新しい関数を作る。
■それ以外は同じ関数インスタンスを再利用。
使う場面
■子コンポーネントにコールバック関数を渡すとき
(React.memo で無駄な再レンダーを防ぐ)
■イベントハンドラ関数を安定させたいとき
import React, { useState, useCallback, memo } from "react";
// 子コンポーネント
const ChildButton = memo(({ onClick }: { onClick: () => void }) => {
console.log("👶 ChildButtonレンダー");
return <button onClick={onClick}>子ボタンをクリック</button>;
});
export const UseCallbackExample = () => {
const [count, setCount] = useState(0);
// useCallbackを使わない場合 → 毎回新しい関数になる
const handleClick = useCallback(() => {
console.log("クリックされました");
}, []); // 依存がないので常に同じ関数参照を維持
return (
<div>
<h2>useCallbackの例</h2>
<p>count: {count}</p>
<button onClick={() => setCount((c) => c + 1)}>+1</button>
<ChildButton onClick={handleClick} />
</div>
);
};
👉 count を増やしても、子の ChildButton は再レンダーされません!
(useCallback がなければ、毎回新しい関数として再レンダーされてしまう)
| フック | メモする対象 | よく使う場面 | 効果 |
|---|---|---|---|
useMemo |
値(計算結果やオブジェクト) | 重い計算、配列・オブジェクト生成 | 再計算を防ぐ |
useCallback |
関数 | 子コンポーネントに渡す関数 | 無駄な再レンダーを防ぐ |
⚠️ 注意点
なんでもかんでもuseMemo/useCallbackを使うのはNG!
■コードが読みにくくなる
■メモリを多く使う場合がある
実際に遅くなることもある(軽い処理なら不要)
👉 「レンダーごとに重い処理が走る」
または
「props経由で再レンダーが起きて困る」
というときだけ使いましょう。