组件状态

setState 做了什么?

setState() 用于安排一个组件的 state 对象的一次更新。当状态改变时,组件通过重新渲染来响应。

state 和 props 之间有什么区别?

props (简称“属性”)和 state 都是在改变时会触发一次重新渲染的 JavaScript 对象。虽然两者都具有影响渲染输出的信息,但它们在一个重要方面是不同的: props 传递到组件(类似于函数参数),而 state 是在组件内管理的(类似于函数中声明的变量)。

这里有一些很好的资源,用以进一步了解何时使用 props vs state

为什么 setState 给我传递了错误值?

setState 的调用是异步的 - 在调用 setState 之后,不要依赖 this.state 来立即反映新值。如果你需要基于当前状态的计算值(请参阅下面的详细信息),则传递更新函数而不是对象。

代码将不会按预期方式运行的示例:

incrementCount() {
  // Note: this will *not* work as intended.
  this.setState({count: this.state.count + 1});
}

handleSomething() {
  // Let's say `this.state.count` starts at 0.
  this.incrementCount();
  this.incrementCount();
  this.incrementCount();
  // When React re-renders the component, `this.state.count` will be 1, but you expected 3.

  // This is because `incrementCount()` function above reads from `this.state.count`,
  // but React doesn't update `this.state.count` until the component is re-rendered.
  // So `incrementCount()` ends up reading `this.state.count` as 0 every time, and sets it to 1.

  // The fix is described below!
}

接着看如果解决这个问题。

如果用依赖于当前状态的值更新状态?

传递一个函数而不是对象给 setState 来确保调用总是使用最新的状态(接着往下看)。

在 setState 中传递一个对象或者一个函数有什么区别?

传递一个更新函数允许你在更新中访问当前的状态值。由于 setState 调用是批处理的,这允许你链式更新并确保它们建立在彼此之上,而不是产生冲突:

incrementCount() {
  this.setState((prevState) => {
    // Important: read `prevState` instead of `this.state` when updating.
    return {count: prevState.count + 1}
  });
}

handleSomething() {
  // Let's say `this.state.count` starts at 0.
  this.incrementCount();
  this.incrementCount();
  this.incrementCount();

  // If you read `this.state.count` now, it would still be 0.
  // But when React re-renders the component, it will be 3.
}

了解有关 setState 的更多

什么时候 setState 异步?

目前,setState 在事件处理程序中是异步的。

例如,如果 ParentChild 在点击事件期间调用 setState ,这确保了 Child 不会重新渲染两次。 相反,React 在浏览器事件结束时 “刷新” 状态(state) 更新。 这可以在较大的应用程序中显着提高性能。

这是一个实现细节,因此请避免直接依赖它。 在未来的版本中,React 将在更多情况下默认批量更新。

为什么 React 不同步更新 this.state

如前一节所述,React 故意“等待”,直到所有组件在开始重新渲染之前在其事件处理程序中调用setState()。 这可以避免不必要的重新渲染,从而提高性能。

但是,您可能仍然想知道为什么 React 不会立即更新 this.state 而不重新渲染。

主要有两个原因:

  • 这会打破propsstate之间的一致性,导致很难调试的问题。
  • 这将使我们正在努力实现的一些新功能无法实现。

这个GitHub评论 深入探讨了具体的例子。

我是否应该使用一个像 Redux 或者 Mobx 的状态管理库?

也许。

在添加额外的库之前,首先了解 React 是个好主意。你可以只使用 React 来构建相当复杂的应用程序。