【问题标题】:Calling setState with nested object does not update state correctly使用嵌套对象调用 setState 不会正确更新状态
【发布时间】:2018-04-25 20:34:59
【问题描述】:

我有一个 React 组件,它维护几个子组件的状态。通过componentDidMount()我在父组件中从子组件调用这个函数:

change = (fieldset, field, data) => {
  this.setState({
    [fieldset]: {
      ...this.state[fieldset],
      [field]: data,
    }
  })
}

考虑使用模式的表单/字段集/字段,但字段调用上述函数。

我遇到的问题是,我相信我会通过快速连续多次调用此函数来混淆 React,因为除了一两个项目之外,状态不会更新。

我尝试使用Object.assign() 来避免改变状态,但在大多数情况下,即使在我开始读取当前开始时,状态也没有正确更新。

这是否违反 React 最佳实践?有没有更好的方式让子组件在父组件中调用setState

【问题讨论】:

  • 为什么不使用 setState() 的更新功能?
  • 我不确定您所说的“更新程序功能”是什么意思?
  • 只是仔细检查一下,change() 是否是父级中的一个函数,它作为道具传递给子级,然后他们会在更改某些内容时调用它?
  • @Toby reactjs.org/docs/react-component.html#setstate 其中 setState() 并不总是立即更新组件。它可能会批量更新或将更新推迟到以后。这使得在调用setState() 之后立即阅读this.state 是一个潜在的陷阱。相反,使用 componentDidUpdate 或 setState 回调 (setState(updater, callback)),它们都保证在应用更新后触发。如果您需要根据之前的状态设置状态,请阅读下面的 updater 参数。
  • @samanime 是正确的。

标签: javascript reactjs


【解决方案1】:

由于更新状态的方式取决于状态本身,因此您需要使用函数而不是对象。

change = (fieldset, field, data) => {
  this.setState(prevState => ({
    [fieldset]: {
      ...prevState[fieldset],
      [field]: data,
    }
  }))
}

函数将一个接一个地应用。因此,您不会覆盖任何待处理的更改。

来自docs

this.setState({quantity: this.state.quantity + 1})

this.setState({quantity: this.state.quantity + 1})

后续调用将覆盖之前调用的值 循环,所以数量只会增加一次。如果接下来 状态取决于之前的状态,我们建议使用更新程序 而是函数形式。

【讨论】:

  • 是的,这就是我的意思。
  • 这很好用 - 抱歉@ArupRakshit,我没有意识到这是你的意思。
  • state 参数指的是 prevstate?
  • @Omar 我不喜欢称它为“prev”。因为实际上它在某种意义上不是以前的,而是当前状态,包括到目前为止应用的未决更改。
  • docs 说 prevstate,但我可以看到你来自哪里
猜你喜欢
  • 1970-01-01
  • 2019-05-31
  • 2020-01-30
  • 1970-01-01
  • 1970-01-01
  • 2019-06-13
  • 1970-01-01
  • 2019-12-23
  • 1970-01-01
相关资源
最近更新 更多