問題:使用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 來觀察狀態變化。
解決此問題的替代方法包括:
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3