【问题标题】:this.state inside setState ReactJSsetState ReactJS 中的 this.state
【发布时间】:2019-01-19 21:59:38
【问题描述】:

所以我对 ReactJS 中 setState 的异步性质有些困惑。 根据 React 文档,您不应该在 setState() 中使用 this.state。但是,如果我有一个计数器作为状态并且我想像这样在点击时更新它:

class App extends React.Component {
    state = { counter: 0 }

    onClick = () => {
        this.setState({counter: this.state.counter + 1})
    }

    render() {
        return (
          <div>
            <div>{this.state.counter}</div>
            <p onClick={this.onClick}>Click me</p>
          </div>
        )
    }
}

这按预期工作。那么为什么这段代码是错误的呢?

更新:我知道 setState 是异步的,它接受具有先前状态作为参数的回调,但我不知道为什么我应该在这里使用它?我想引用setState里面的旧状态,那么为什么要在这种情况下使用回调函数呢?每当this.setState()被执行时,它里面的this.state总是引用旧的状态,它的值只有在setState执行完成后才会被改变为新的状态,而不是在它正在执行的时候。

【问题讨论】:

标签: javascript reactjs


【解决方案1】:

您可以在 setState 调用中访问prevState

this.setState((prevState) => ({
    counter: prevState.counter +1
}))

这将允许您安全地增加当前状态值。

React 文档总结了为什么在更新期间不能依赖 this.state 来保持准确:https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous

【讨论】:

  • 但是this.state 里面的setState 不是已经在我的代码中引用了之前的状态吗?那么为什么在这种情况下使用 setState 回调呢?
  • @maverick 因为 React 可以并且将会批处理 setState 调用,所以不能保证调用会在什么时候被触发。这意味着它将在可能错误的时间从this.state 读取。使用回调是从 setState 调用中访问先前状态的最安全方法。
  • 我知道 setState 是异步的。这意味着它不会立即被调用。但是当它被调用时, this.state 仍然会引用旧状态,这就是我在这种情况下想要访问的状态。 this.state 将在 setState 完成执行后更新其值,但不会在执行时更新。
  • React 文档总结了为什么你不应该比我更好地依赖this.state,他们甚至有一个反例。答案已更新
  • 请参阅官方文档中的示例:reactjs.org/docs/hooks-state.html 他们使用的地方: 所以我也像@maverick 一样糊涂了。
【解决方案2】:

setState 接受一个函数作为参数,之前的状态作为参数。 重构如下以避免竞争问题:

onClick = () => {
    this.setState(prevState => ({counter: prevState.counter + 1}))
}

【讨论】:

  • 什么补全问题?能给我举个例子吗?我知道 setState 接受回调,但我不确定为什么要在这种情况下使用它?
  • @maverick 由于setState 是异步的,因此您不能假设this.state 是您更新的最后一个值。看看这个:stackoverflow.com/a/48209870/5735030.
猜你喜欢
  • 1970-01-01
  • 2014-12-12
  • 2018-11-24
  • 1970-01-01
  • 2017-02-08
  • 2016-05-20
  • 1970-01-01
  • 2018-10-04
  • 1970-01-01
相关资源
最近更新 更多