💡 React.memoとは
React.memo は 「コンポーネントをメモ化する」 高階コンポーネント(HOC)です。
つまり、同じ props であれば再レンダーをスキップしてくれます。
const Child = React.memo(({ value }) => {
console.log("👶 子コンポーネントがレンダーされました");
return <p>値: {value}</p>;
});
上のように React.memo() でラップすると、親コンポーネントが再レンダーされても、props.value が変わらなければ再レンダーされません。
🧩 例:React.memo なし・ありの違い
❌ なしの場合
const Child = ({ value }) => {
console.log("👶 子コンポーネントがレンダーされました");
return <p>値: {value}</p>;
};
→ 親が再レンダーされるたびに、子も再レンダーされます。
✅ ありの場合
const Child = React.memo(({ value }) => {
console.log("👶 子コンポーネントがレンダーされました");
return <p>値: {value}</p>;
});
→ value が変わらない限り、子は再レンダーされません。
⚙️ useMemoとの違いを整理してみよう
React.memo と useMemo は似た名前ですが、目的がまったく異なります。
| 比較対象 | メモ化の対象 | 目的 | 使用場所 |
|---|---|---|---|
| React.memo | コンポーネントの出力(JSX) | 子コンポーネントの再レンダーを防ぐ | コンポーネント定義の外側 |
| useMemo | 値(関数の戻り値) | 重い計算結果の再計算を防ぐ | コンポーネント内部 |
🧩 サンプルコード
import React, { useState } from "react";
// ✅ memoなしバージョン
const ChildNormal = ({ value }) => {
console.log("👶 ChildNormal(memoなし)がレンダーされました");
return <p>値: {value}</p>;
};
// ✅ memoありバージョン
const ChildMemo = React.memo(({ value }) => {
console.log("🧠 ChildMemo(memoあり)がレンダーされました");
return <p>値: {value}</p>;
});
function App() {
const [count, setCount] = useState(0);
const [text, setText] = useState("");
console.log("🔁 親コンポーネントがレンダーされました");
return (
<div style={{ padding: "20px", fontFamily: "sans-serif" }}>
<h2>React.memo 比較デモ</h2>
<div style={{ marginBottom: "20px" }}>
<button onClick={() => setCount((prev) => prev + 1)}>
数値を増やす(count: {count})
</button>
<input
style={{ marginLeft: "10px" }}
value={text}
onChange={(e) => setText(e.target.value)}
placeholder="テキストを入力"
/>
</div>
<h3>① 普通の子コンポーネント(memoなし)</h3>
<ChildNormal value={count} />
<h3>② React.memo でラップした子コンポーネント</h3>
<ChildMemo value={count} />
</div>
);
}
export default App;
🔍 実行してみよう
操作1:テキスト入力
親の text ステートが変わりますが、
ChildNormal → 再レンダリングされる
ChildMemo → 再レンダリングされない
→ コンソールで次のように確認できます👇
🔁 親コンポーネントがレンダーされました
👶 ChildNormal(memoなし)がレンダーされました
テキスト入力をしても ChildMemo は再レンダーされないため、
「🧠 ChildMemo(memoあり)がレンダーされました」
はコンソールに 表示されません
操作2:数値を増やすボタン
count(propsとして渡している値)が変わるため、 ChildMemo も再レンダリングされます。
→ コンソールで次のように確認できます👇
🔁 親コンポーネントがレンダーされました
👶 ChildNormal(memoなし)がレンダーされました
🧠 ChildMemo(memoあり)がレンダーされました
🧠 まとめ
| 用途 | メモ化するもの | よく使う組み合わせ |
|---|---|---|
| 重い計算の結果を保持 | useMemo |
- |
| 関数を再生成しない | useCallback |
+ React.memo
|
| コンポーネントを再レンダーしない | React.memo |
+ useCallback or useMemo
|
✅ 覚え方:
-
値を覚える → useMemo
-
関数を覚える → useCallback
-
コンポーネントを覚える → React.memo
🏁 最後に
Reactのパフォーマンス最適化は、 「何を止めたいのか」 を意識すると一気に理解が深まります。
-
コンポーネントの再描画を止めたい → React.memo
-
計算やオブジェクトの再生成を止めたい → useMemo
このように整理しておくと、次に学ぶ useCallback もスムーズに理解できます。
最後までご覧いただきありがとうございました。useCallbackの記事も併せてご覧いただけると幸いです。