简体   繁体   English

React useEffect:返回函数中的setState没有及时更新状态

[英]React useEffect: setState in return function does not update state in time

I have made an example here: https://codesandbox.io/s/cocky-brattain-de5r4我在这里做了一个例子: https : //codesandbox.io/s/cocky-brattain-de5r4

I'm making a tabbed interface when switching from one to another, a component should first unregister itself (clearing some values from parent state) through the useEffect return function, and re-register itself (set some values in the parent).我在从一个切换到另一个时制作了一个选项卡式界面,一个组件应该首先通过useEffect返回函数取消注册自己(从父状态清除一些值),然后重新注册自己(在父级中设置一些值)。 However, the clean up doesn't seem to work.但是,清理似乎不起作用。 ie the value does not change before the register function starts.即该值在寄存器功能开始之前不会改变。

Look at the console log, the first time it logs an empty object, as the initial value.查看控制台日志,第一次记录一个空对象,作为初始值。 But when clicking on tab20, the logged value shows what it is before unregistering.但是当点击 tab20 时,记录的值显示的是注销前的值。

What is the problem here?这里有什么问题?

What I'm expecting to happen is:我期待发生的是:

(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 (应用加载)-> 控制台日志:{} -> [注册]aaa 设置为 1 ->(切换选项卡)-> [取消注册]aaa 设置为未定义 -> 控制台日志:{aaa:未定义(但它是 1) } -> [注册]aaa 设置为 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 (应用加载)-> 控制台日志:{} -> [注册]aaa 设置为 1 ->(切换选项卡)-> [取消注册]aaa 设置为未定义 -> 控制台日志:{aaa:未定义(但它是 1) } -> [注册]aaa 设置为 1

Actually its:其实它的:

(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) (应用加载) -> 控制台日志 (myVal):{} -> [register]aaa 设置为 1 -> (switch tab) -> 使用 (myVal = {aaa:1}) 更新注册中的闭包 -> [取消注册]aaa 设置为未定义 -> 控制台日志:{aaa: 1}(因为之前的关闭)

The problem is when you switching tab, the components re-renders and the register function is re-declared which is updating its closure ( myVal ).问题是当您切换选项卡时,组件会重新渲染,并且会重新声明register函数,该函数正在更新其闭包 ( myVal )。

To fix it (the logging result), get rid of the closure:要修复它(日志结果),去掉闭包:

const register = useCallback(name => {
  setMyVal(prevState => {
    console.log(prevState);
    return { ...prevState, [name]: 1 };
  });
}, []);

编辑amazing-boyd-d6s3g

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM