簡體   English   中英

帶有回調的 useState 不更新 useCallback 依賴項

[英]useState with callback not updating useCallback dependencies

我在這里做了一個工作示例: https://codesandbox.io/s/magical-flower-o0gyn?file=/src/App.js

當我單擊隱藏按鈕時,我想將更新的數據保存到本地存儲:

  1. 我單擊第一列上的隱藏: setValueWithCallback運行,將回調設置為 ref 並設置 state
  2. useEffect啟動,使用更新的數據調用回調
  3. saveToLocalStorage在使用data集作為依賴的useCallback中被調用

問題出在第三步,保存到本地存儲的是{visible: true} 我知道如果我改變這一行:

const saveToLocalStorage = useCallback(() => {
  localStorage.setItem(
    `_colProps`,
    JSON.stringify(data.map((e) => ({ id: e.id, visible: e.visible })))
  );
}, [data]);

對此:

const saveToLocalStorage = localStorage.setItem(
  `_colProps`,
  JSON.stringify(data.map((e) => ({ id: e.id, visible: e.visible })))
);

它有效,但我無法理解,為什么第一個沒有。 我認為它一定是一些關閉的東西,但我沒有看到它。

如果data已經更新,並且useEffect運行了回調,為什么它沒有在依賴數組中更新? 是的,這個例子很奇怪,第二個解決方案很好,我只是想演示這個問題。 謝謝您的幫助!

代碼中的問題是由於組件的本地 state 上的saveToLocalStorage function 關閉。

setValueWithCallback function 中,您使用傳遞給setValueWithCallback ZC1C425268E68385D1AB5074C17A9 的callback參數保存對saveToLocalStorage function 的引用,這就是您的問題所在。

useCallback掛鈎將更新saveToLocalStorage function 的 function 引用,但您不會將其稱為更新的 function。 相反,您調用您保存在callbackRef.current中的 function,它不是更新的 function,而是一個舊的,它對visible對象的值都設置為true有一個閉包。

解決方案

您可以通過將data作為參數傳遞給回調 function 來解決此問題。 當您調用callbackRef.current(data)時,您已經傳遞了參數,但您沒有在saveToLocalStorage function 中使用它。

更改saveToLocalStorage以使用從useEffect掛鈎內部傳遞的參數。

const saveToLocalStorage = useCallback((updatedData) => {
    localStorage.setItem(
      `_colProps`,
      JSON.stringify(updatedData.map((e) => ({ id: e.id, visible: e.visible })))
    );
}, []); 

解決此問題的另一種方法是擺脫callbackRef並從useEffect掛鈎內部調用saveToLocalStorage function。

useEffect(() => {
    saveToLocalStorage();
}, [data, saveToLocalStorage]);

您的data屬於數組類型,並且僅在發生 state 更新時才進行shallow comparison ,因此基本上它會檢查data參考更改而不是其值更改。 這就是為什么當data's值發生變化時,您的 saveToLocalStorage 不會重新啟動。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM