React における Pure コンポーネント:仕組みと使用タイミング

React の Pure コンポーネントはパフォーマンスに関するものです。コンポーネントの入力(propsまたはstate)が実際に変更されたかどうかをチェックすることで、アプリケーションが不要な再レンダリングを回避するのに役立ちます。この記事では、Pure コンポーネントの仕組み、使用方法、そして明確で最新の例を交えて、いつ役立つかを見ていきます。
重要なポイント
- React における「純粋な」コンポーネントの特徴を学ぶ
React.PureComponent
またはReact.memo
を使用するタイミングを確認する- 浅い比較(shallow comparison)と再レンダリングへの影響を理解する
Pure コンポーネントとは?
Pure コンポーネントは、props または state が変更された場合にのみ再レンダリングされるコンポーネントです。React は現在の props/state と以前のものとの浅い比較を行うことで、再レンダリングすべきかどうかを判断します。
React.PureComponent
の使用
React.PureComponent
は純粋関数に相当するクラスコンポーネントです。浅い比較を実行する組み込みの shouldComponentUpdate()
メソッドを実装しています。
class MyComponent extends React.PureComponent {
render() {
return <div>{this.props.text}</div>;
}
}
this.props.text
が変更されていない場合、コンポーネントは再レンダリングされません。
関数型の代替手段:React.memo
関数コンポーネントでは、React.memo()
を使用します。
const MyComponent = React.memo(function MyComponent({ text }) {
return <div>{text}</div>;
});
text
が前回のレンダリング時と同じであれば、React はレンダリングをスキップします。
浅い比較の仕組み
浅い比較とは:
- プリミティブ値(数値や文字列など)は値で比較される
- オブジェクトと配列は参照で比較される
{ a: 1 } === { a: 1 } // false
const obj = { a: 1 }
obj === obj // true
そのため、再作成ではなく変更されるオブジェクトを渡す場合、Pure コンポーネントは変更に気づかない可能性があります。
実際の例
最適化なし
const Item = ({ data }) => <div>{data.label}</div>;
これは、data
が変更されていなくても、親が再レンダリングされるたびに再レンダリングされます。
React.memo
を使用
const Item = React.memo(({ data }) => <div>{data.label}</div>);
これで、data
が新しいオブジェクトの場合にのみコンポーネントが再レンダリングされます。
PureComponent または memo を使用するタイミング
- 多くの項目を含むリストをレンダリングする場合
- コンポーネントの props がレンダリング間で安定している場合
- パフォーマンスに敏感なアプリの部分でレンダリングサイクルを減らしたい場合
- 参照を保持するために
useCallback
またはuseMemo
を使用している場合
よくある落とし穴
- 浅い比較は深い変更(ネストされたオブジェクト/配列)を検出しない
- props が暗黙的に変更されないと確信できない限り使用しない
- 不安定な参照を渡すとバグが発生する可能性がある
React.memo
vs React.PureComponent
機能 React.PureComponent
React.memo
コンポーネントタイプ クラスコンポーネント 関数コンポーネント 比較ロジック Props + state(浅い) Props のみ(浅い) カスタム比較関数 ❌ ✅ React.memo(fn)
現代の使用法 あまり一般的でない 広く使用されている
結論
Pure コンポーネントは React が再レンダリングをスキップし、UI のパフォーマンスを維持するのに役立ちますが、万能薬ではありません。関数コンポーネントには React.memo
を優先し、浅い比較では参照が重要であることを理解しましょう。パフォーマンスが重要で props が安定している場合に使用してください。
よくある質問
props/state が変更されていない場合(浅い比較を使用して)、不要な再レンダリングを防ぎます。
関数コンポーネントが安定した props を受け取り、再レンダリングが無駄になる場合に使用します。
いいえ。浅い比較を使用します。オブジェクトや配列をその場で変更することは避けるべきです。