ホームページ  >  記事  >  ウェブフロントエンド  >  React Memo を使用して不必要な再レンダリングに別れを告げる: ステップバイステップのチュートリアル

React Memo を使用して不必要な再レンダリングに別れを告げる: ステップバイステップのチュートリアル

Patricia Arquette
Patricia Arquetteオリジナル
2024-11-12 13:54:02383ブラウズ

Say Goodbye to Unnecessary Re-Renders with React Memo: Step-by-Step Tutorial

React Memo: シンプルなメモ化で React のパフォーマンスを向上させる

導入

React アプリケーションは大規模なデータセットや複雑なコンポーネントを扱うことが多く、不必要な再レンダリングがパフォーマンスに大きな影響を与える可能性があります。これに対処するために、React は、コンポーネントを最適化し、レンダリング時間を短縮するためのシンプルかつ強力なツールである React.memo を提供します。このガイドでは、React Memo がどのように機能するか、なぜそれが役立つのか、そしてそれを段階的に実装する方法について説明します。


Reactメモとは何ですか?

React.memo は、機能コンポーネントのメモ化を支援する React の高次コンポーネント (HOC) です。メモ化は、関数の入力に基づいて関数の出力をキャッシュするプロセスであるため、関数は同じ入力に対して結果を再計算する必要がありません。 React Memo も同様に動作します。コンポーネントの最後にレンダリングされた出力を「記憶」し、プロパティが変更された場合にのみ再レンダリングします。

なぜリアクションメモなのか?

React では、親コンポーネントが再レンダリングされるたびに、コンポーネントも再レンダリングされます。コンポーネントの出力がその親の変更に依存しない場合、これにより非効率が生じる可能性があります。たとえば、多くのコンポーネントを含む複雑な UI では、過剰な再レンダリングにより遅延が発生する可能性があります。 React Memo を使用すると、必要な場合にのみコンポーネントを更新することでこれを最適化できます。


React Memo が解決する問題

1. 不必要な再レンダリング

親コンポーネントが再レンダリングされると、その子コンポーネントも同様に再レンダリングされます。これは、特にコンポーネントが静的データを表示する場合、または不変の props に依存する場合に、パフォーマンスのボトルネックにつながる可能性があります。

2. 複雑な UI でのパフォーマンスの遅れまたは遅さ

コンポーネントが深くネストされているアプリケーションでは、累積的な再レンダリングによりパフォーマンスが低下する可能性があります。 React Memo を使用したメモ化は、更新を必要としないコンポーネントの再レンダリングを防ぎ、アプリの応答性を向上させます。


React Memo の仕組み: ステップバイステップの例

React Memo の基本的な実装を見てみましょう。メモ化を使用しない単純なコンポーネントから始めて、React Memo を追加することでどのような違いが生じるかを見ていきます。

ステップ 1: React Memo を使用しない単純なカウンター コンポーネントをセットアップする

import React, { useState } from 'react';

function Counter({ count }) {
  console.log('Counter component re-rendered');
  return <h1>Count: {count}</h1>;
}

function App() {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');

  return (
    <div>
      <Counter count={count} />
      <button onClick={() => setCount(count + 1)}>Increment Count</button>
      <input type="text" value={text} onChange={(e) => setText(e.target.value)} placeholder="Type something..." />
    </div>
  );
}

export default App;

説明

この例では、入力フィールドに入力するたびに、カウント値は同じであっても、Counter コンポーネントが再レンダリングされます。これは不要な再レンダリングですが、React Memo を使用することで防ぐことができます。

ステップ 2: React Memo を使用した最適化

次に、Counter コンポーネントを React.memo でラップして最適化しましょう。

import React, { useState } from 'react';

function Counter({ count }) {
  console.log('Counter component re-rendered');
  return <h1>Count: {count}</h1>;
}

function App() {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');

  return (
    <div>
      <Counter count={count} />
      <button onClick={() => setCount(count + 1)}>Increment Count</button>
      <input type="text" value={text} onChange={(e) => setText(e.target.value)} placeholder="Type something..." />
    </div>
  );
}

export default App;

説明

React.memo を使用すると、Counter コンポーネントは count プロパティが変更された場合にのみ再レンダリングされます。入力フィールドに入力しても Counter の再レンダリングがトリガーされなくなり、パフォーマンスが大幅に最適化されました。


React Memo の実際の動作: リストを使用した実践的なシナリオ

React Memo の本当の利点を確認するために、より複雑な例を見てみましょう。各アイテムの横に「いいね」ボタンがあるアイテムのリストがあるとします。 React Memo が個々のアイテムにいいねをするときに過剰な再レンダリングをどのように防ぐことができるかを示します。

ステップ 1: メモなしでリスト コンポーネントを作成する

import React, { useState } from 'react';

const Counter = React.memo(function Counter({ count }) {
  console.log('Counter component re-rendered');
  return <h1>Count: {count}</h1>;
});

function App() {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');

  return (
    <div>
      <Counter count={count} />
      <button onClick={() => setCount(count + 1)}>Increment Count</button>
      <input type="text" value={text} onChange={(e) => setText(e.target.value)} placeholder="Type something..." />
    </div>
  );
}

export default App;

問題

上記のコードでは、1 つのアイテムに「いいね!」を付けると、たとえ 1 つのアイテムの「いいね!」が変更されただけであっても、すべてのアイテムが再レンダリングされます。

ステップ 2: React Memo を使用して項目コンポーネントを最適化する

import React, { useState } from 'react';

function Item({ item, onLike }) {
  console.log(`Rendering ${item.name}`);
  return (
    <div>
      <h2>{item.name}</h2>
      <button onClick={() => onLike(item.id)}>Like</button>
    </div>
  );
}

function ItemList() {
  const [items, setItems] = useState([
    { id: 1, name: 'Item 1', likes: 0 },
    { id: 2, name: 'Item 2', likes: 0 },
    { id: 3, name: 'Item 3', likes: 0 },
  ]);

  const handleLike = (id) => {
    setItems((prevItems) =>
      prevItems.map((item) =>
        item.id === id ? { ...item, likes: item.likes + 1 } : item
      )
    );
  };

  return (
    <div>
      {items.map((item) => (
        <Item key={item.id} item={item} onLike={handleLike} />
      ))}
    </div>
  );
}

export default ItemList;

結果

クリックして「いいね!」したアイテムのみが再レンダリングされるようになり、UI がより高速かつ効率的になりました。


React Memo をいつ使用するか?

React Memo は特定のシナリオで役立ちますが、あらゆる場所で使用すると、実際の利点が得られずにコードが複雑になる可能性があります。特に効果的となる重要な状況をいくつか示します:

  1. 静的コンポーネント: ヘッダーやフッターなど、頻繁に変更されないコンポーネント。
  2. 純粋な機能コンポーネント: レンダリングのための小道具のみに依存するコンポーネント。
  3. コンポーネントの大規模なリスト: 不必要な再レンダリングを避ける必要がある多くの項目を含むリスト。

潜在的な落とし穴とベストプラクティス

  1. 浅い比較: React Memo は浅い比較を行います。つまり、深くネストされたオブジェクトや配列の変更は検出されません。複雑な props を渡す場合は、useMemo または useCallback の使用を検討してください。

  2. パフォーマンス監視: React DevTools を使用して、どのコンポーネントが実際にメモ化の恩恵を受けるかを特定します。 React Memo を使いすぎると、コードが複雑になり、パフォーマンスの向上は無視できるほどになる可能性があります。


よくある質問 (FAQ)

Q1: React Memo は useMemo や useCallback とどう違うのですか?

  • React Memo は、props に基づいてコンポーネントの再レンダリングを最適化します。
  • useMemo は、計算された値をコンポーネント内にキャッシュします。
  • useCallback は関数をキャッシュし、レンダリングのたびに関数が再作成されるのを防ぎます。

Q2: React Memo をクラスコンポーネントで使用できますか?

いいえ、React Memo は機能コンポーネントのみを対象としています。ただし、クラス コンポーネントの場合は、PureComponent を使用して同様の動作を実現できます。


結論

React Memo は、不必要な再レンダリングを減らし、React アプリケーションのパフォーマンスを向上させる貴重なツールです。純粋な機能コンポーネントまたは静的 UI 要素で選択的に使用することで、構造を複雑にすることなく React アプリを最適化できます。以下の手順に従い、例を試し、実験を続けてプロジェクトに最適なメモ化戦略を見つけてください!

以上がReact Memo を使用して不必要な再レンダリングに別れを告げる: ステップバイステップのチュートリアルの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。