【実務・中級編】 純粋コンポーネントの概念 – React実践ガイド

Reactの「純粋コンポーネント」を極める:なぜ、どうやってパフォーマンスを制御するのか

現場でReactを書いていると、ふと「このコンポーネント、今のレンダリングで本当に再実行する必要ある?」と疑問に思う瞬間が必ず来るはずだ。特にアプリケーションが肥大化してくると、無駄な再レンダリングが積もり積もって、ユーザーの操作に微妙な「モタつき」が生じる。

今日は、その泥沼から脱出するための最短ルートであり、Reactパフォーマンス最適化の原点である「純粋コンポーネント(Pure Component)」の概念について、実務の視点で深掘りしていく。

—

「純粋」であるとはどういうことか?

純粋コンポーネントとは、数学的な関数と同じで、「同じPropsが渡されたら、何度実行されても全く同じ結果(JSX)を返す」コンポーネントのことだ。

これを阻害するのは、例えば以下のようなコードだ。

// ❌ アンチパターン:純粋ではないコンポーネント
const UserProfile = ({ name }) => {
// コンポーネント内でランダム値や現在時刻を生成している
// Propsが変わらなくても、レンダリングのたびに結果が変わってしまう
const timestamp = new Date().getTime();

return

{name} – {timestamp}

;
};

Reactは親コンポーネントが更新されると、その配下にあるコンポーネントをデフォルトで「再レンダリング」しようとする。たとえPropsの中身が同じであってもだ。もし、この`UserProfile`のようなコンポーネントが巨大なツリーの中に100個あれば、ブラウザは無意味な計算と仮想DOMの差分比較を100回繰り返すことになる。これが「重い」原因だ。

—

裏側でブラウザは何をしているのか?

Reactが「再レンダリングするかどうか」を判断する際、裏側では「Propsの浅い比較(Shallow Comparison)」が行われている。

1. レンダリングのトリガー: 親がStateを更新する。
2. 差分検知: Reactは仮想DOM上で新しいツリーと古いツリーを比較する。
3. 純粋性の活用: `React.memo`などでラップされたコンポーネントは、「Propsが以前と全く同じ(参照透過性が保たれている)」と判断できれば、コンポーネント関数そのものの実行をスキップする。

この「スキップ」こそが、パフォーマンス最適化の聖杯だ。JavaScriptの実行時間を削り、DOM操作を最小限に抑える。これが、モダンフロントエンドの腕の見せ所だよ。

—

実践:`React.memo`で無駄を削ぎ落とす

現場で一番使うのが `React.memo` だ。これを使うだけで、不必要な再レンダリングを劇的に減らせる。

import React, { memo } from ‘react’;

/

  • React.memoでラップすることで、
  • Propsが浅い比較で一致する場合、再レンダリングをスキップする

/
const UserCard = memo(({ name, onClick }) => {
console.log(“UserCardがレンダリングされました”); // デバッグ用

return (

ユーザー名: {name}

);
});

// 使用例
const App = () => {
const [count, setCount] = React.useState(0);
const [userName] = React.useState(“Taro”);

// ここで気をつけるべきは、関数の参照が毎回変わらないようにすること!
// useCallbackでラップしないと、React.memoが意味をなさなくなる。
const handleClick = React.useCallback(() => {
console.log(“Clicked!”);
}, []);

return (
<>

{/ countが変わっても、userNameとhandleClickが変わらない限りUserCardは再実行されない /}


);
};

現場で陥りやすい「罠」

ここで一つ、シニアとしてのアドバイスだ。「とりあえず全部 `memo` すればいい」というのは間違いだ。

`React.memo` は、比較のためのコストを支払っている。Propsが頻繁に変わるコンポーネントに適用しても、比較した結果「やっぱり再レンダリングが必要だ」となれば、単に比較のオーバーヘッドが加わるだけで逆効果になる。

  • 適材適所の判断基準:
  • 適用すべき: レンダリングコストが高いコンポーネント(リスト内のアイテムなど)。
  • 適用しなくていい: 描画がシンプルで、常にPropsが更新されるようなコンポーネント。

—

まとめ:次にあなたがやるべきこと

1. 「レンダリングが重い」と感じたら: まず `React DevTools` の「Profiler」で、どのコンポーネントが再レンダリングされているかを確認する。
2. 純粋性を意識する: コンポーネント外の変数に依存したり、レンダリング中に副作用(非純粋な処理)を混ぜる癖を捨てる。
3. 参照の安定性を保つ: `useCallback` や `useMemo` をセットで使い、Propsの参照が変わらないようにケアする。

Reactを「なんとなく」書く段階から、「なぜ再レンダリングされるのか」を制御できる段階へ。この一歩を踏み出すだけで、君が書くコードの質は劇的に変わる。

現場のコードは生き物だ。理論を理解した上で、泥臭くブラウザの挙動と対話してほしい。応援しているよ。

コメント

タイトルとURLをコピーしました