即使在 setState 回调中,解构状态也不会更新

Posted

技术标签:

【中文标题】即使在 setState 回调中,解构状态也不会更新【英文标题】:Deconstructed state is not updated even in the setState callback 【发布时间】:2019-12-21 01:03:18 【问题描述】:

有一个问题是解构组件的状态会阻止它在 setState 中更新:

state = 
   value: 'test',
   values: ['a', 'b', 'c'],
;

...

const  value, values  = this.state;

this.setState(
  
    values: [...values, value],
  ,
  () => 
    console.log(values);
    // this logs ["a", "b", "c"] rather than ["a", "b", "c", "test"]
  
);

值的预期输出应该包含新值,但它只记录旧值。使用“this.state”的工作原理只是想知道为什么解构状态对象似乎没有正确更新?

如果您单击按钮并检查控制台日志,您可以转到此Codesandbox 并亲自尝试一下。

对此的任何帮助将不胜感激!

【问题讨论】:

它正在更新,但您打印的是旧值而不是新值。因此,如果您单击该按钮两次,您将看到更新。 你必须控制台日志this.state.values。 values 仍然指的是引用旧 this.state.values 的局部变量 对提供的答案发表了评论,但是感谢您的解释! 【参考方案1】:

假设如下:

state = value: 0
foo = () =>
    const  value  = this.state
    this.setState(value : value + 1, () => console.log(value)) //0

发生这种情况是因为value 保存了调用方法foo() 时的状态值,即使在状态更新后此const 的值也不会改变,因为它相当于:const value = this.state.value。这是这个值曾经是什么的参考。在这种情况下使用state 的全局实例来访问更新后的值

this.setState(value : value + 1, () => console.log(this.state.value))//1

【讨论】:

啊,好吧。我想在 render() 函数中执行它不是问题,因为 this.state 的 const 每次绘制都会被重新分配,因此可以在那里工作,但不能在渲染之外。感谢您的解释! 没错。可以在 render 中执行它,因为每次状态更改时都会调用它,因此它始终保持当前状态【参考方案2】:

也许你可以尝试这样的事情:

state = 
   value: 'test',
   values: ['a', 'b', 'c'],
;

this.setState(oldState => 
  const  value, values  = oldState;
  return 
    values: [...values, value],
  ,
  () => 
    console.log(values);
    // this logs ["a", "b", "c"] rather than ["a", "b", "c", "test"]
  
);

在您的示例中,您尝试打印状态的旧值,即在 setState 之前刚刚发生的值。因此,您基本上是在将值设置为以前的值。 setState 实际上还接受一个回调函数,您可以从中提取旧状态。在那里你可以解构值等等。试试看,祝你好运!

【讨论】:

以上是关于即使在 setState 回调中,解构状态也不会更新的主要内容,如果未能解决你的问题,请参考以下文章

我的有状态小部件不会更新 ui,即使我正在调用 setState 并将正确的值传递给小部件类

为啥即使在有状态小部件中使用 setstate 也无法获取更新的变量。因为我想在新的 TabBar 选项上更新我的 Container

setState详解

ReactJS 状态未更新在 setState 回调中

在等待之后调用 setState 时,状态立即可用

React setState 不适用于 if 语句