Reactのヒントはフックの依存関係の問題を解消する方法を教えます

Reactのヒントはフックの依存関係の問題を解消する方法を教えます

reactプロジェクトで非常に一般的なシナリオ:

const [watchValue、setWatchValue] = useState('');
const [otherValue1, setOtherValue1] = useState('');
const [otherValue2, setOtherValue2] = useState('');

使用効果(() => {
    何かを実行します(他の値1、他の値2);
}, [watchValue, otherValue1, otherValue2]);

watchValueが変更されたときにdoSomethingを実行し、他の値otherValue1otherValue2を参照します。

ここで厄介な疑問が浮かびます。

  • otherValue1otherValue2依存関係配列に追加されていない場合、 doSomething otherValue1otherValue2の古い変数参照にアクセスする可能性が高く、予期しないエラーが発生します ( hooks関連のeslintがインストールされている場合は、警告が表示されます)。
  • 逆に、 otherValue1otherValue2依存関係配列に追加されると、これら 2 つの値が変更されたときにdoSomethingも実行されますが、これは望ましいことではありません (値を参照するだけで、 doSomethingをトリガーしたくはありません)。

この問題は、 otherValue1otherValue2 refに変更することで解決できます。

const [watchValue、setWatchValue] = useState('');
const other1 = useRef('');
other2 は useRef() を使用します。

// 参照は変更されないため、依存関係配列に ref を追加する必要はありません useEffect(() => {
    何かを実行します(other1.current、other2.current);
}, [ウォッチ値]);

この方法では、 other1other2の変数参照は変更されないため、前の問題は解決されますが、新しい問題が発生します。other1 とother2 other1 currentの値が変更されても、コンポーネントの再レンダリングはトリガーされません ( useRef的current変更によってコンポーネントのレンダリングがトリガーされることはありません)。そのため、値が変更されてもインターフェイスは更新されません。

これはhooksでは頭痛の種です。useState useStateは再レンダリングをトリガーし、インターフェースを最新の状態に保ちますが、 useEffectの依存関係として使用されると、常に不要な関数の実行をトリガーします。 useRef変数はuseEffect依存関係として安全に使用できますが、コンポーネントのレンダリングはトリガーされず、インターフェースは更新されません。
どうすれば解決できるでしょうか?

useRefuseStateの機能を組み合わせて、新しいhooks関数useStateRefを構築できます。

「react」から useState、useRef をインポートします。

// useState の応答性を維持しながら useRef の参照特性を使用する type StateRefObj<T> = {
  _状態: T;
  値: T;
};
デフォルト関数 useStateRef<T>( をエクスポートする
  初期状態: T | (() => T)
): StateRefObj<T> {
  // 初期化値 const [init] = useState(() => {
    if (typeof initialState === "function") {
      初期状態を () => T として返します ();
    }
    初期状態を返します。
  });
  // コンポーネントのレンダリングをトリガーする状態を設定します。const [, setState] = useState(init);
  
  // 値を読み取ると、最新の値が取得されます // 値を設定すると、setStateがトリガーされ、コンポーネントがレンダリングされます const [ref] = useState<StateRefObj<T>>(() => {
    戻る {
      _状態: 初期化、
      値を設定する(v: T) {
        this._state = v;
        状態を設定します。
      },
      値を取得する() {
        this._state を返します。
      },
    };
  });
  
  // 返されるのは参照変数であり、コンポーネントのライフサイクル全体を通じて変更されません。 return ref;
}

したがって、次のように使用できます。

定数ウォッチ = useStateRef('');
const other1 = useStateRef('');
const other2 = useStateRef('');

// 値を次のように変更します: watch.value = "new";

使用効果(() => {
    何かを実行します(other1.値、other2.値);
   // 実際、これら 3 つの値は参照変数となり、コンポーネントのライフサイクル全体で変更されないため、依存関係配列を追加する必要はありません。 // ただし、React Hooks の eslint プラグインは、useRef を参照としてのみ認識できます。追加されていない場合は警告が表示されます。変数参照の安全性のため、引き続き追加されます。 }, [watch.value, other1, other2]);

このように、 watch, other1other2 useRefの参照機能を持ち、 doSomethingの不要な実行をトリガーしません。 useStateの応答性により、 .valueを変更すると、コンポーネントのレンダリングとインターフェースの更新がトリガーされます。
変数の変更によってdoSomethingをトリガーしたい場合は、依存関係配列にwatch.valueを追加します。値を参照するだけでdoSomethingをトリガーしたくない場合は、変数自体を配列に追加します。

上記は、フック依存性のトラブルを解消するためのReactのヒントの詳細です。Reactフック依存性の詳細については、123WORDPRESS.COMの他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • React Hooksの詳細な説明
  • React Hooksを使用する際のよくある落とし穴
  • 30分でReact Hooksを包括的に理解できます
  • Reactフックの仕組み
  • Reactフックの長所と短所
  • React のクラスからフックへの移行

<<:  実稼働環境でのNginx高可用性ソリューションの実装プロセスの分析

>>:  CentOS 7 での mysql 5.7 のインストール チュートリアル

推薦する

MySQL 8.0.12 解凍バージョンのインストールチュートリアル

この記事では、MySQL 8.0.12解凍版のインストールチュートリアルを参考までに紹介します。具体...

ボタントリガーイベントを使用して背景色の点滅効果を実現します

背景色の点滅効果を実現するには、次のコードを <body> 領域に追加するだけです。コー...

MySQL スケジュールされたデータベース バックアップ操作の例

この記事では、MySQL のスケジュールされたデータベース バックアップ操作の例について説明します。...

Docker プライベートリポジトリの管理とローカルリポジトリ内のイメージの削除

1: Dockerプライベートウェアハウスのインストール1. イメージリポジトリからイメージをダウン...

UDP シンプル サーバー クライアント コード例

UDP の理論については詳しく説明しません。UDP に関する HelloWorld プログラムを紹介...

Reactにおけるキーの役割の詳細な説明

目次質問: ボタンをクリックすると、スパンの色が赤に変わりますか?上記の問題を分析します。 2番目の...

HTML ウェブページでのアンカー(名前付きアンカー)の使用の概要

以下の情報はインターネットから収集したものです1. アンカーは、Web ページ作成におけるハイパーリ...

MySQL のロック待機とデッドロック問題の分析

目次序文: 1. ロック待機とデッドロックを理解する2. 現象の再発と治療要約:序文: MySQL ...

デザインにおけるユーザーエクスペリエンスの背後にある8つのユーザー本能について話す

編集者注: この記事は、Teambition チームの @娄昊川 が寄稿したものです。Teambit...

MySQL でストアド プロシージャを作成し、データ テーブルに新しいフィールドを追加する方法の分析

この記事では、例を使用して、MySQL でストアド プロシージャを作成し、データ テーブルに新しいフ...

MySQLはカスタム関数を使用して親IDまたは子IDを再帰的に照会します

背景: MySQL では、レベルに制限がある場合、たとえば、ツリーの最大深度を事前に決定できる場合、...

Web ページ WB.ExecWB 制御印刷メソッド呼び出しの説明とパラメータの紹介

WebページWB.ExecWB制御印刷方法コードをコピーコードは次のとおりです。 <テーブルの...

ウェブメッセージボード機能を実現するjs

この記事の例では、Webメッセージボードを実装するためのjsの具体的なコードを参考までに共有していま...

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

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

非常に詳細な Vue-Router のステップバイステップのチュートリアル

目次1. ルータビュー2. ルータリンク3. リダイレクト4. ルーティングエイリアス5. ルーティ...