mar*_*llo 3 reactjs react-hooks usecallback
我在这里做了一个工作示例: https://codesandbox.io/s/magical-flower-o0gyn ?file=/src/App.js
当我单击隐藏按钮时,我想将更新的数据保存到本地存储:
setValueWithCallback运行,将回调设置为引用并设置状态useEffect启动,使用更新的数据调用回调saveToLocalStorage在设置为依赖项的useCallback情况下被调用data问题出在第三步,保存到本地存储的内容适用{visible: true}于两者。我知道如果我改变这一行:
const saveToLocalStorage = useCallback(() => {
localStorage.setItem(
`_colProps`,
JSON.stringify(data.map((e) => ({ id: e.id, visible: e.visible })))
);
}, [data]);
Run Code Online (Sandbox Code Playgroud)
对此:
const saveToLocalStorage = localStorage.setItem(
`_colProps`,
JSON.stringify(data.map((e) => ({ id: e.id, visible: e.visible })))
);
Run Code Online (Sandbox Code Playgroud)
它有效,但我无法理解,为什么第一个不起作用。我认为这一定是一些关闭的事情,但我没有看到它。
如果data已经更新,并useEffect运行了回调,为什么它没有在依赖项数组中更新?是的,这个例子很奇怪,第二个解决方案非常好,我只是想演示这个问题。谢谢您的帮助!
saveToLocalStorage代码中的问题是由于组件的本地状态上的函数关闭所致。
在函数内部setValueWithCallback,您saveToLocalStorage使用callback传递给函数的参数保存对setValueWithCallback函数的引用,这就是您的问题所在。
useCallbackhook 将更新函数的函数引用saveToLocalStorage,但您不会调用该更新的函数。相反,您调用保存在其中的函数,该函数callbackRef.current不是更新的函数,而是一个旧函数,该函数对状态有一个闭包,visible两个对象中的属性值都设置为true。
您可以通过将data作为参数传递给回调函数来解决此问题。您在调用时已经传递了参数callbackRef.current(data),但没有在saveToLocalStorage函数内使用它。
更改saveToLocalStorage以使用从挂钩内部传递的参数useEffect。
const saveToLocalStorage = useCallback((updatedData) => {
localStorage.setItem(
`_colProps`,
JSON.stringify(updatedData.map((e) => ({ id: e.id, visible: e.visible })))
);
}, []);
Run Code Online (Sandbox Code Playgroud)
解决此问题的另一种方法是摆脱钩子并仅从钩子内部callbackRef调用该函数。saveToLocalStorageuseEffect
useEffect(() => {
saveToLocalStorage();
}, [data, saveToLocalStorage]);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7366 次 |
| 最近记录: |