ホームページ  >  記事  >  ウェブフロントエンド  >  React フックとイベント リスナーを使用すると、ステート コンソール ログに間違った情報が表示されるのはなぜですか?

React フックとイベント リスナーを使用すると、ステート コンソール ログに間違った情報が表示されるのはなぜですか?

Barbara Streisand
Barbara Streisandオリジナル
2024-10-18 20:13:30630ブラウズ

When Using React Hooks and Event Listeners, Why Does the State Console Log Display Incorrect Information?

イベント リスナーと React フック

問題: React フックとイベント リスナーを使用すると、状態コンソール ログに誤った情報が表示されます。

問題の説明

提供されている CodeSandbox: https://codesandbox.io/s/lrxw1wr97m を考えてみましょう。 [カードの追加] ボタンを 2 回クリックし、最初のカードの [ボタン 1] をクリックすると、コンソールには 2 枚のカードがある状態が正しく表示されます。ただし、同じカード (イベント リスナーによって処理される) の「Button2」をクリックすると、コンソールにはその状態のカードが 1 枚だけ誤って表示されます。

状態が正しくない理由

この問題は、CardsProvider コンポーネントと Card コンポーネントでのイベント ハンドラーの処理が異なるために発生します。 CardsProvider 機能コンポーネント内で定義されたイベント ハンドラー、handleCardClick および handleButtonClick は、コンポーネントがレンダリングされるたびに再定義されます。これは、それらが定義された時点の状態を参照することを意味し、イベント リスナーがトリガーされると、その状態が失効する可能性があります。

一方、Card コンポーネントは useRef を使用してイベント リスナーを登録します。イベント リスナーは永続化されます。コンポーネントのライフサイクル全体にわたって。その結果、イベント リスナー関数は、コンポーネントがマウントされた時点の状態を参照します。これは古い状態です。

解決策 - 状態アップデーター関数を使用する

1 つの解決策は、状態アップデーターを使用することです。囲んでいるスコープからの古い状態に依存するのではなく、引数として新しい状態を受け取る関数:

<code class="javascript">const eventListener = () => {
  // Function receives fresh state
  setState(freshState => freshState + 1);
};

// Event listener is registered using `useEffect` to ensure it is only registered once
useEffect(() => {
  // Register event listener
  // ...

  // Unregister event listener on component unmount
  return () => {
    // ...
  };
}, []);</code>

このシナリオでは、イベント リスナーは新しい状態を受け取り、古いデータの問題を排除します。ただし、状態アップデータ関数は不要な更新を防ぐために同じ状態を返すことができることに注意することが重要です。状態アップデータ関数内で console.log を使用して、状態の変化を観察します。

その他の解決策

この問題に対処する別の方法には次のようなものがあります。

  • 可変状態: useState の代わりに useRef を使用します。
  • 手動イベント リスナー再登録: 状態が変化するたびにイベント リスナーを再登録します。
  • 組み込みイベント処理: カスタム イベント リスナーではなく、React の組み込みイベント処理を使用します。

以上がReact フックとイベント リスナーを使用すると、ステート コンソール ログに間違った情報が表示されるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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