Reactjs 带有回调的useState不更新useCallback依赖项
我在这里举了一个工作示例: 单击“隐藏”按钮时,我希望将更新的数据保存到localstorage:Reactjs 带有回调的useState不更新useCallback依赖项,reactjs,react-hooks,usecallback,Reactjs,React Hooks,Usecallback,我在这里举了一个工作示例: 单击“隐藏”按钮时,我希望将更新的数据保存到localstorage: 我单击第一列上的隐藏:setValueWithCallbackruns,将回调设置为ref&设置状态 useffect启动,使用更新的数据调用回调 在useCallback中调用saveToLocalStorage,并将data设置为依赖项 问题是在第三步,保存到localstorage的内容是{visible:true}。 我知道如果我改变这一行: const saveToLocalStora
setValueWithCallback
runs,将回调设置为ref&设置状态useffect
启动,使用更新的数据调用回调useCallback
中调用saveToLocalStorage
,并将data
设置为依赖项{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
已经更新,并且useffect
运行了回调,那么为什么不在dependencies数组中更新它呢?。
是的,这个例子很奇怪,第二个解决方案非常好,我只是想演示一下这个问题。
谢谢你的帮助 您的
数据
属于数组类型,并且在发生状态更新时只进行浅层比较
,因此基本上它将检查数据
参考更改,而不是其值更改。这就是为什么当数据的
值更改时,您的saveToLocalStorage不会重新启动。您的数据
是数组类型,并且在发生状态更新时只会进行浅层比较
,因此基本上它会检查数据
引用更改,而不会检查其值更改。这就是为什么当数据的
值更改时,您的saveToLocalStorage不会重新启动。代码中的问题是由于组件的本地状态关闭了saveToLocalStorage
功能
在setValueWithCallback
函数中,使用传递给setValueWithCallback
函数的callback
参数保存对saveToLocalStorage
函数的引用,这就是问题所在
useCallback
hook将更新saveToLocalStorage
函数的函数引用,但您不调用更新后的函数。相反,您可以调用保存在callbackRef.current
中的函数,该函数不是更新后的函数,而是一个旧函数,它在状态上有一个闭包,两个对象中的visible
属性都设置为true
解决方案
您可以通过将数据作为参数传递给回调函数来解决此问题。调用callbackRef.current(data)
时已经传递了参数,但在saveToLocalStorage
函数中没有使用它
更改saveToLocalStorage
以使用从useffect
钩子内部传递的参数
const saveToLocalStorage = useCallback((updatedData) => {
localStorage.setItem(
`_colProps`,
JSON.stringify(updatedData.map((e) => ({ id: e.id, visible: e.visible })))
);
}, []);
useEffect(() => {
saveToLocalStorage();
}, [data, saveToLocalStorage]);
解决此问题的另一种方法是去掉callbackRef
,只需从useffect
钩子内部调用saveToLocalStorage
函数
const saveToLocalStorage = useCallback((updatedData) => {
localStorage.setItem(
`_colProps`,
JSON.stringify(updatedData.map((e) => ({ id: e.id, visible: e.visible })))
);
}, []);
useEffect(() => {
saveToLocalStorage();
}, [data, saveToLocalStorage]);
代码中的问题是由于在组件的本地状态上关闭了saveToLocalStorage
函数
在setValueWithCallback
函数中,使用传递给setValueWithCallback
函数的callback
参数保存对saveToLocalStorage
函数的引用,这就是问题所在
useCallback
hook将更新saveToLocalStorage
函数的函数引用,但您不调用更新后的函数。相反,您可以调用保存在callbackRef.current
中的函数,该函数不是更新后的函数,而是一个旧函数,它在状态上有一个闭包,两个对象中的visible
属性都设置为true
解决方案
您可以通过将数据作为参数传递给回调函数来解决此问题。调用callbackRef.current(data)
时已经传递了参数,但在saveToLocalStorage
函数中没有使用它
更改saveToLocalStorage
以使用从useffect
钩子内部传递的参数
const saveToLocalStorage = useCallback((updatedData) => {
localStorage.setItem(
`_colProps`,
JSON.stringify(updatedData.map((e) => ({ id: e.id, visible: e.visible })))
);
}, []);
useEffect(() => {
saveToLocalStorage();
}, [data, saveToLocalStorage]);
解决此问题的另一种方法是去掉callbackRef
,只需从useffect
钩子内部调用saveToLocalStorage
函数
const saveToLocalStorage = useCallback((updatedData) => {
localStorage.setItem(
`_colProps`,
JSON.stringify(updatedData.map((e) => ({ id: e.id, visible: e.visible })))
);
}, []);
useEffect(() => {
saveToLocalStorage();
}, [data, saveToLocalStorage]);
这个useCallback(()=>{
不是useCallback((数据)=>{
?您正在向回调函数传递一个参数,但回调函数定义不带任何参数。我认为您不需要参数。如果您检查react文档,它将在没有参数的情况下使用。因此回调函数神奇地可以访问参数值?在您的代码示例中,数据
是本地sta组件的te,而不是调用callbackRef.current(data)时传递的参数;
抱歉,我不清楚这一点。我不关心参数。在回调内部,我引用的是组件的本地状态。我只想有一个机制,首先更新状态,完成后调用回调(保存到本地存储)。当回调启动时,依赖项数组中的数据
是否应该已经更新?如果在第一次单击后单击另一个按钮,则一个对象被正确保存,因此它落后于一个周期。我可能会误解useCallback
的工作方式。我认为当依赖项数组中的某些内容发生更改时,会生成一个新的f函数体中包含最新值。此useCallback(()=>{
不应该是useCallback((数据)=>{
)吗?您正在向回调函数传递参数,但回调函数定义不接受任何参数。我不知道