0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

🧠 React.memoとは?useMemoとの違いをやさしく解説

Posted at

💡 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 値(関数の戻り値) 重い計算結果の再計算を防ぐ コンポーネント内部

🧩 サンプルコード

App.jsx
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 → 再レンダリングされない
→ コンソールで次のように確認できます👇

console
🔁 親コンポーネントがレンダーされました
👶 ChildNormal(memoなし)がレンダーされました

テキスト入力をしても ChildMemo は再レンダーされないため、
「🧠 ChildMemo(memoあり)がレンダーされました」
はコンソールに 表示されません

操作2:数値を増やすボタン
count(propsとして渡している値)が変わるため、 ChildMemo も再レンダリングされます。
→ コンソールで次のように確認できます👇

console
🔁 親コンポーネントがレンダーされました
👶 ChildNormal(memoなし)がレンダーされました
🧠 ChildMemo(memoあり)がレンダーされました

🧠 まとめ

用途 メモ化するもの よく使う組み合わせ
重い計算の結果を保持 useMemo -
関数を再生成しない useCallback + React.memo
コンポーネントを再レンダーしない React.memo + useCallback or useMemo

✅ 覚え方:

  • 値を覚える → useMemo

  • 関数を覚える → useCallback

  • コンポーネントを覚える → React.memo

🏁 最後に

Reactのパフォーマンス最適化は、 「何を止めたいのか」 を意識すると一気に理解が深まります。

  • コンポーネントの再描画を止めたい → React.memo

  • 計算やオブジェクトの再生成を止めたい → useMemo

このように整理しておくと、次に学ぶ useCallback もスムーズに理解できます。

最後までご覧いただきありがとうございました。useCallbackの記事も併せてご覧いただけると幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?