問題: 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 を使用して、状態の変化を観察します。
この問題に対処する別の方法には次のようなものがあります。
以上がReact フックとイベント リスナーを使用すると、ステート コンソール ログに間違った情報が表示されるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。