React useMemo と useCallback の使用シナリオ

React useMemo と useCallback の使用シナリオ

メモを使う

親コンポーネントが再レンダリングされると、そのすべての要素 (状態、ローカル変数など) が新しくなることはわかっています。子コンポーネントが親コンポーネントのオブジェクト変数に依存すると、オブジェクトが変更されたかどうかに関係なく、子コンポーネントは新しいオブジェクトを取得し、子コンポーネントに対応する diff が無効になり、ロジックが再実行されます。次の例では、副作用依存関係に親コンポーネントから渡されたオブジェクト パラメータが含まれており、親コンポーネントが更新されるたびにデータ要求がトリガーされます。

関数情報({
  スタイル、
}) {
  console.log('情報のレンダリングが行われます');

  使用効果(() => {
    console.log('データを再読み込み'); // 再レンダリングが発生するたびにデータが再読み込みされます}, [style]);

  戻る (
    <p スタイル={スタイル}>
      これは情報内のテキストです</p>
  );
}

関数ページ() {
  console.log('ページのレンダリング');

  定数[count, setCount] = useState(0);
  const スタイル = { 色: '赤' };

  // カウンターが +1 になると、ページが再レンダリングされ、その結果、Info の再レンダリングがトリガーされます (
    <div>
      <h4>カウント値: {count}</h4>
      <button onClick={() => setCount(count + 1)}> +1 </button>
      <情報スタイル={スタイル} />
    </div>
  );
}

React Hooks は解決策を提供します。useMemo を使用すると、渡されたオブジェクトをキャッシュし、依存関係が変更された場合にのみ、対応するオブジェクトを再計算して更新できます。

関数ページ() {
  console.log('ページのレンダリング');

  const [色] = useState('赤');
  定数[count, setCount] = useState(0);
  const style = useMemo(() => ({ color }), [color]); // スタイルは色が大幅に変更された場合にのみ変更されます // カウンターが +1 になると、ページの再レンダリングがトリガーされ、次に情報の再レンダリングがトリガーされます // ただし、スタイルはキャッシュされているため、情報のデータの再読み込みはトリガーされません return (
    <div>
      <h4>カウント値: {count}</h4>
      <button onClick={() => setCount(count + 1)}> +1 </button>
      <情報スタイル={スタイル} />
    </div>
  );
}

コールバックの使用

React Hooks はデータ フローに 2 つの変更をもたらします。1 つ目は、状態管理のためのコンテキストのより使いやすい使用をサポートし、レイヤーが多すぎる場合に無関係なパラメーターが中間レイヤーに転送されることを回避します。2 つ目は、関数がデータ フローに参加できるようにし、冗長なパラメーターが下位レベルのコンポーネントに転送されることを回避します。

フックのコア モジュールの 1 つとして、useContext は渡されたコンテキストの現在の値を取得して、レイヤー間通信を実現します。 Reactの公式サイトに詳しい紹介があります。注意すべき点は、コンテキスト値が変わると、そのコンテキストを使用しているすべてのコンポーネントが再レンダリングされることです。無関係なコンポーネントの再描画を避けるためには、コンテキストを合理的に構築する必要があります。たとえば、最初のセクションで説明した新しい思考モードから始めて、状態の関連性に応じてコンテキストを整理し、関連する状態を同じコンテキストに保存することができます。

従来、親コンポーネントと子コンポーネントが同じデータ要求メソッド getData を使用し、このメソッドが上位層から渡されるクエリ値に依存する場合、通常はクエリメソッドと getData メソッドを一緒に子コンポーネントに渡す必要がありました。子コンポーネントはクエリ値を判断して getData を再実行するかどうかを決定していました。

クラス Parent は React.Component を拡張します {
   状態 = {
    クエリ: 'キーワード',
  }

  取得データ() {
    定数 url = `https://mocks.alibaba-inc.com/mock/fO87jdfKqX/demo/queryData.json?query=${this.state.query}`;
    // データを要求します...
    console.log(`リクエストパス: ${url}`);
  }

  与える() {
    戻る (
      // 子コンポーネントがレンダリングしないクエリ値を渡す <Child getData={this.getData} query={this.state.query} />
    );
  }
}

クラスChildはReact.Componentを拡張します。
  コンポーネントマウント() {
    このプロパティは、次の例のように機能します。
  }

  コンポーネントが更新されました(前のプロパティ) {
    // if (prevProps.getData !== this.props.getData) { // この条件は常に真です
    // this.props.getData();
    // }
    if (prevProps.query !== this.props.query) { // 判断にはクエリ値のみを使用できます this.props.getData();
    }
  }

  与える() {
    戻る (
      // ...
    );
  }
}

React Hooks では、useCallback を使用すると関数をキャッシュし、依存関係が変更された場合にのみ更新できます。これにより、子コンポーネントで useEffect を使用してオンデマンド読み込みを実現できます。フックの連携により、関数は単なるメソッドではなく、値としてアプリケーションのデータ フローに参加できるようになります。

関数親() {
  定数[count, setCount] = useState(0);
  const [クエリ、setQuery] = useState('キーワード');

  定数 getData = useCallback(() => {
    url に `https://mocks.alibaba-inc.com/mock/fO87jdfKqX/demo/queryData.json?query=${query}` を追加します。
    // データを要求します...
    console.log(`リクエストパス: ${url}`);
  }, [query]); // getData はクエリが変更された場合にのみ更新されます // カウント値の変更によって、子がデータの再要求を行うことはありません (
    <>
      <h4>カウント値: {count}</h4>
      <button onClick={() => setCount(count + 1)}> +1 </button>
      <input onChange={(e) => {setQuery(e.target.value)}} />
      <子 getData={getData} />
    </>
  );
}

関数Child({
  データを取得
}) {
  使用効果(() => {
    データを取得します。
  }, [getData]); // 関数は依存関係としてデータフローに参加できます return (
    // ...
  );
}

以上がReact useMemoとuseCallbackの使用シナリオの詳細な内容です。React useMemoとuseCallbackの使用の詳細については、123WORDPRESS.COMの他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • React.memo() を使用して関数コンポーネントのパフォーマンスを最適化する方法の詳細な説明
  • React.memo によって発生したバグを覚えておいてください

<<:  データベース接続のURLの詳細な説明と概要

>>:  Docker 大規模プロジェクトのコンテナ化変革

推薦する

MySQL グローバルロックとテーブルレベルロックの具体的な使用法

目次序文グローバルロックテーブルロックテーブルロックメタデータ ロック (MDL ロック)要約する参...

React Hooks に基づく小さな状態管理の詳細な説明

目次React Hooks に基づく状態共有の実装ユーザーエクスペリエンスこの記事では、主に Rea...

MySQL の CPU 負荷が高い問題のトラブルシューティング

MySQL による CPU 負荷の上昇今日の午後、MySQL によってサーバーの負荷が高くなる問題を...

Dockerコンテナが起動直後に終了する問題を解決する

最近、Docker がコンテナの起動時に特定のプロセスを直接実行できるようにする方法を調べていたとこ...

Webpack ファイル パッケージ化エラー例外

webpack をパッケージ化する前に、次の作業が完了していることを確認する必要があります。 1) ...

Linux にソフトウェアをインストールするときにソフトウェア パッケージが存在しない問題を解決する方法

ソフトウェア パッケージが存在しない場合は、インストールされているソフトウェアのソフトウェア ソース...

Linux で MySQL データベースのインポートおよびエクスポート コマンドを実装する方法

1. mysqldump コマンドを使用してデータベースをエクスポートします (このコマンドのパスで...

bodyタグの主な属性の概要

bgcolor="テキストの色" background="背景画像&q...

Tomcat Nginx Redis セッション共有プロセス図

1. 準備ミドルウェア: Tomcat、Redis、Nginx Jar パッケージ: commons...

CSS3 フレックスレイアウトを使用して要素を均等に分散するサンプルコード

この記事では主に、CSS3 フレックスレイアウトを使用して要素を均等に配置する方法を紹介します。自分...

Velocity.js はページスクロール切り替え効果を実装します

今日は、複数ページのスクロール切り替え効果を備えた Web サイトを簡単かつ効率的に開発できる、小さ...

Linux でタスク用のカスタム システム トレイ インジケーターを作成する

システム トレイ アイコンは、今日でも魔法のような機能です。アイコンを右クリックして目的のアクション...

Jenkins の紹介と Docker で Jenkins をデプロイする方法

1. 関連概念1.1 Jenkins の概念: Jenkins は、使用されるプラットフォームに関係...

layui をベースにしたログインページの実装

この記事の例では、ログインページを実装するためのlayuiの具体的なコードを参考までに共有しています...

Docker構成 Alibaba Cloud Container Serviceの操作

Alibaba Cloud Dockerコンテナサービスの設定Alibaba Cloud Image...