什么时候可以依赖 this.state 的值进行react?

IT技术 reactjs
2022-07-29 01:48:53

我是 React 新手,正在阅读 React 网站上的教程。在分步教程中,有一节解释了您不应该依赖 state 的值来计算下一个 state,因为 state 更新是异步的。相反,他们解释说,您应该使用一个版本的 setState,它接受一个函数,将前一个状态作为参数传递给该函数。

但是,在实践教程中,出现了以下代码:

handleClick(i) {
    const squares = this.state.squares.slice();
    squares[i] = this.state.xIsNext ? 'X' : 'O';
    this.setState({
      squares: squares,
      xIsNext: !this.state.xIsNext,
    });
  }

其中 setState 调用传递了一个对象,该对象依赖于 this.state 中的值。为什么这段代码没问题,为什么在这种情况下不必担心异步 setState 执行?我试图了解何时可以直接依赖我的 React 代码中 this.state 的值。

提前致谢!

2个回答

教程的解释是错误的。在很多情况下,您可以直接依赖引用this.state,包括代码片段中的案例。

仅在以下情况下直接引用this.state才是问题

  • 您之前已使用该组件调用this.setState过,并且
  • 该组件尚未重新渲染,并且
  • 您想this.setState再次调用,同时考虑刚刚设置的值

this.state如果以上任何一个条件为假,不使用回调版本,通过引用来设置状态就可以了。

例如,在您问题的片段中,我假设这handleClick是一个点击处理程序,并且没有其他点击处理程序运行 - 在您调用之前不会调用不同的状态设置器this.setState({ squares ...,所以没有问题。

但是,如果您按顺序调用多个s,那将是有问题的。handleClick例如,如果你有类似的东西

handleMultipleClicks() {
  for (let i = 0; i < 5; i++) {
    handleClick(i);
  }
}

以上将是一个问题,因为您this.setState在让组件有机会重新渲染之前多次调用;this.state.squares循环的第二次(和进一步)迭代中引用的 不会反映在循环this.setState的第一次迭代中传递给的值。

一种思考方式是:this.state将在最后一次重新渲染结束时引用状态。如果您在编写代码时考虑到这一点,您将能够可靠地确定是否需要使用状态设置器的回调版本。

在您的示例中,您没有立即使用该状态,setState因此它按预期工作。考虑这个示例,由于异步状态更新,您可能会得到一些意外结果。

handleClick(i) {
  console.log(this.state.value); // 1, can be any value
  this.setState({
    value: this.state.value + 1
  });
  console.log(this.state.value); // This is still 1, or the prev value
}

此外,您似乎正在使用Class组件,因此教程可能很旧。我还建议您学习功能组件和钩子。它会让你的生活更轻松:)