React useEffect: return 函数中的 setState 没有及时更新状态
React useEffect: setState in return function does not update state in time
我在这里做了一个例子:
https://codesandbox.io/s/cocky-brattain-de5r4
我正在制作一个选项卡式界面,当从一个切换到另一个时,组件应该首先通过 useEffect
return 函数注销自身(从父状态清除一些值),然后重新注册自己(在父级中设置一些值)。但是,清理似乎不起作用。即在寄存器函数启动之前该值不会改变。
看控制台日志,第一次记录一个空对象,作为初始值。但是当点击 tab20 时,记录的值会显示注销前的值。
这里有什么问题?
我期待的是:
(App load) -> console log: {} -> [register]aaa set to 1 -> (switch tab) -> [unregister]aaa set to undefined -> console log: {aaa: undefined(but it is 1)} -> [register]aaa set to 1
(App load) -> console log: {} -> [register]aaa set to 1 -> (switch tab) -> [unregister]aaa set to undefined -> console log: {aaa: undefined(but it is 1)} -> [register]aaa set to 1
实际上是:
(App load) -> console log (myVal):{} -> [register]aaa set to 1 -> (switch tab) ->
update the closure within register with (myVal = {aaa:1}) -> [unregister]aaa set to undefined -> console log: {aaa: 1} (because of previous closure)
问题是当您切换选项卡时,组件重新呈现并且 register
函数被重新声明,它正在更新其闭包 (myVal
)。
要修复它(日志记录结果),去掉闭包:
const register = useCallback(name => {
setMyVal(prevState => {
console.log(prevState);
return { ...prevState, [name]: 1 };
});
}, []);
我在这里做了一个例子: https://codesandbox.io/s/cocky-brattain-de5r4
我正在制作一个选项卡式界面,当从一个切换到另一个时,组件应该首先通过 useEffect
return 函数注销自身(从父状态清除一些值),然后重新注册自己(在父级中设置一些值)。但是,清理似乎不起作用。即在寄存器函数启动之前该值不会改变。
看控制台日志,第一次记录一个空对象,作为初始值。但是当点击 tab20 时,记录的值会显示注销前的值。
这里有什么问题?
我期待的是:
(App load) -> console log: {} -> [register]aaa set to 1 -> (switch tab) -> [unregister]aaa set to undefined -> console log: {aaa: undefined(but it is 1)} -> [register]aaa set to 1
(App load) -> console log: {} -> [register]aaa set to 1 -> (switch tab) -> [unregister]aaa set to undefined -> console log: {aaa: undefined(but it is 1)} -> [register]aaa set to 1
实际上是:
(App load) -> console log (myVal):{} -> [register]aaa set to 1 -> (switch tab) -> update the closure within register with (myVal = {aaa:1}) -> [unregister]aaa set to undefined -> console log: {aaa: 1} (because of previous closure)
问题是当您切换选项卡时,组件重新呈现并且 register
函数被重新声明,它正在更新其闭包 (myVal
)。
要修复它(日志记录结果),去掉闭包:
const register = useCallback(name => {
setMyVal(prevState => {
console.log(prevState);
return { ...prevState, [name]: 1 };
});
}, []);