」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 使用 React Hooks 和事件監聽器時,為什麼狀態控制台日誌顯示錯誤訊息?

使用 React Hooks 和事件監聽器時,為什麼狀態控制台日誌顯示錯誤訊息?

發佈於2024-11-07
瀏覽:698

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

事件監聽器和React Hooks

問題:使用React hooks和事件監聽器時,狀態控制台日誌顯示不正確的資訊。

問題描述

考慮提供的CodeSandbox:https://codesandbox.io/s/lrxw1wr97m。當您按一下「新增卡片」按鈕兩次,然後按一下第一張卡片中的「Button1」時,控制台會正確顯示有兩張卡片的狀態。但是,如果您按一下同一張卡中的「Button2」(由事件偵聽器處理),控制台會錯誤地僅顯示一張卡片的狀態。

狀態不正確的原因

問題源自於 CardsProvider 和 Card 元件中事件處理程序的不同處理。每次呈現該元件時,都會重新定義 CardsProvider 功能元件中定義的事件處理程序(handleCardClick 和 handleButtonClick)。這意味著它們引用的是定義時的狀態,當觸發事件偵聽器時,該狀態可能會過時。

另一方面,Card 元件使用 useRef 註冊事件偵聽器,此事件偵聽器會持續存在貫穿元件的整個生命週期。因此,事件偵聽器函數引用元件安裝時的狀態,該狀態已過時。

解決方案- 使用狀態更新器函數

一個解決方案是使用狀態更新器接收新鮮狀態作為參數的函數,而不是依賴於封閉範圍中的陳舊狀態:

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 () => {
    // ...
  };
}, []);

在這種情況下,事件偵聽器接收最新狀態,從而消除了陳舊資料的問題。但是,請務必注意,狀態更新器函數可以傳回相同的狀態以防止不必要的更新。在狀態更新器函數中使用 console.log 來觀察狀態變化。

其他解決方案

解決此問題的替代方法包括:

  • Mutable State: 使用 useRef 而不是 useState。
  • 手動事件監聽器重新註冊: 每次狀態變更時重新註冊事件監聽器。
  • 內建事件處理:使用React的內建事件處理而非自訂事件監聽器。
版本聲明 本文轉載於:1729253539如有侵犯,請洽[email protected]刪除
最新教學 更多>

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3