ReactJS 中 this.state 和 this.setstate 的区别是什么?

IT技术 javascript reactjs asynchronous
2021-02-02 23:36:05

我想更改hasSubmit的值,就像在第一个代码部分一样。我知道这是不推荐的。但是第二个代码是异步的,我不想使用setState.

  • this.state的区别是setState什么?
  • 有没有办法hasSubmit立即改变状态值

第一个代码:

this.state.hasSubmit = false
this.setState({})
//Code that will use `hasSubmit`.

第二个代码:

this.setState({
   hasSubmit: false,
});
//Code that will use `hasSubmit`.

添加:

场景是:

  1. hasSubmit设置falsegetInitialState().
  2. hasSubmitfalse当我单击submit按钮将更改为
  3. hasSubmittrue提交时将更改为

第一次点击submit没有问题,hasSubmit会设置为true

但是第二次点击submit会错误使用Second asynchronous code,因为hasSubmit仍然true,而First Code可以解决问题。

5个回答

这是React 文档所说的:

永远不要this.state直接改变,因为之后调用 setState() 可能会替换你所做的改变。将 this.state 视为不可变的。

setState()不会立即改变 this.state 而是创建一个挂起的状态转换。this.state调用此方法后访问可能会返回现有值。

无法保证对 setState 调用的同步操作,并且可能会批量调用以提高性能。 setState()除非在shouldComponentUpdate().

如果正在使用可变对象并且无法在 中实现逻辑shouldComponentUpdate(),则setState()仅在新状态与先前状态不同时调用将避免不必要的重新渲染。

按照设计的方式使用 API 总是明智的。如果文档说不要改变你的状态,那么你最好不要改变你的状态。

虽然setState()在技​​术上可能是异步的,但它肯定不会以任何明显的方式变慢。组件的render()函数将在很短的时间内被调用。

直接设置状态的一个缺点是 React 的生命周期方法 - shouldComponentUpdate(), componentWillUpdate(), componentDidUpdate()- 依赖于被调用的状态转换setState()如果直接更改状态并setState()使用空对象调用,则无法再实现这些方法。

另一个是它只是糟糕的编程风格。你在两个语句中做你可以在一个语句中做的事情。

此外,这里没有实际的好处。在这两种情况下,render()直到setState()(或forceUpdate()) 被调用后才会被触发

你声称需要这样做,而没有实际解释这种需要是什么。也许您想更详细地说明您的问题。可能有更好的解决方案。

最好使用框架而不是反对它。

更新

从下面的评论:

需要的是我想在下面使用更改后的 hasSubmit。

好的我现在明白了。如果您需要立即使用未来状态属性,最好的办法就是将其存储在局部变量中。

const hasSubmit = false;

this.setState({
  hasSubmit: hasSubmit
});

if (hasSubmit) { 
  // Code that will use `hasSubmit` ...
1) 我明白了。我已经更新了我的答案来解决这个问题。2) 那些生命周期方法不再能this.statenextState或 进行有意义的比较prevState
2021-03-17 23:36:05
我尝试了第一个代码。该方法componentWillUpdate()componentDidUpdate()render()也将被称为和值hasSubmit更改为true
2021-03-18 23:36:05
添加异步回调函数比简单的局部变量要笨拙得多。它也没有抓住重点。不需要查询状态。你不需要得到你刚刚设置的
2021-03-23 23:36:05
需要的是我想使用hasSubmit 下面的更改
2021-03-31 23:36:05
你说维护一个局部变量的事实并不是好的imo。这可以通过作为文档的 setstate 方法的回调来实现。
2021-04-11 23:36:05

如果你想改变状态并通过react触发重新渲染: 使用第二个代码。

  this.setState({
    hasSubmit: false,
  });

第一个代码的问题/错误:

  this.state.hasSubmit = false      // Updates state directly: 
                                    // You are not supposed to do this
                                    // except in ES6 constructors
  this.setState({})                 // passes an empty state to react.
                                    // Triggers re-render without mutating state
你说this code does not use setState callback:但在你使用的两个例子中setState——这是一个错字吗?
2021-03-14 23:36:05
答案清晰易懂
2021-03-27 23:36:05
setState可以采用可选的回调参数。可用于在状态更新后执行某些操作。这不是一个真正的错字:我使用了setState,但没有传递任何回调参数。这确实令人困惑,所以我删除了参考;)
2021-04-02 23:36:05

this.setState维护react组件的生命周期,并且看起来不像变异变量(即使在内部它确实变异了状态)。因此,react循环中的单向流程保持不变,没有任何副作用。

需要注意的是 usingthis.setState不适用于 ES6 类中的构造函数。我们需要使用this.state =模式而不是this.setState在 ES6 构造函数中

this.setState 在构造函数中是不允许的,因为 setState 可以批处理并且是异步的,因此这可能意味着组件最终可能会具有与预期或初始化不同的状态。出于同样的原因,也不鼓励 AJAX 调用。
2021-04-09 23:36:05
是的。非常好的观察,即this.setStateES6 类构造函数中不允许使用语法。可能是因为在构造函数中您没有修改状态,而是第一次初始化它。
2021-04-11 23:36:05

您永远不应该忽略文档建议。在撰写本文时,setState 允许第二个参数,它是 setState 和重新渲染完成时的回调函数。由于您从未向我们提供您的代码将如何使用 hasSubmit 值,我相信其他一些人可能会在他们想要确保 hasSubmit 已更改时发现这很有用。

我相信这应该是答案。正如最佳答案所暗示的那样,无需维护另一个局部变量来保存该值。
2021-03-15 23:36:05

您应该this.forceUpdate()在第一个示例中使用强制更新状态。例如:

this.state.hasSubmit = false;
this.forceUpdate();

但最好使用,this.setState因为它是 React 引擎的 init 本机检查状态机制,比强制更新更好。

如果您只是this.state直接更新任何参数而没有setStatereact渲染 mecanizm 将不知道状态的某些参数已更新。

对于真正深度嵌套的状态 JSON 对象,例如深度嵌套的数组,更新状态setState很痛苦
2021-03-30 23:36:05
正如这里的官方文档:“通常你应该尽量避免使用 forceUpdate() 并且只在 render() 中从 this.props 和 this.state 中读取。” 在这种特殊情况下, forceUpdate() 不是一个好的解决方案。
2021-04-11 23:36:05