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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35867038/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 18:18:49  来源:igfitidea点击:

What the difference of this.state and this.setstate in ReactJS?

javascriptreactjsasynchronous

提问by DanielJyc

I want to change the value for the hasSubmitkey, like in the First Code section. I know this is not recommended. But the second code is asynchronous and I don't want to use the callback function of setState.

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

  • What is the difference of this.stateand setState?
  • Is there any way to change state value hasSubmitimmediately?
  • this.state和的区别是setState什么?
  • 有没有办法hasSubmit立即改变状态值?

First Code:

第一个代码:

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

Second code:

第二个代码:

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


ADD:

添加:

The scenario is that:

场景是:

  1. hasSubmitset falsein getInitialState().
  2. hasSubmitwill change to falsewhen I click submitbutton.
  3. hasSubmitwill change to truewhen submitted.
  1. hasSubmit设置falsegetInitialState().
  2. hasSubmitfalse当我单击submit按钮时将更改为。
  3. hasSubmittrue提交时将更改为。

First click submithas no problem and hasSubmitwill be set to true.

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

But second click submitwill be wrong using the Second asynchronous code, because the hasSubmitis still true, while the First Codecan resolve the problem.

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

回答by David L. Walsh

Here's what the React docssay:

这是React 文档所说的:

NEVER mutate this.statedirectly, as calling setState() afterwards may replace the mutation you made. Treat this.state as if it were immutable.

setState()does not immediately mutate this.state but creates a pending state transition. Accessing this.stateafter calling this method can potentially return the existing value.

There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains. setState()will always trigger a re-render unless conditional rendering logic is implemented in shouldComponentUpdate().

If mutable objects are being used and the logic cannot be implemented in shouldComponentUpdate(), calling setState()only when the new state differs from the previous state will avoid unnecessary re-renders.

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

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

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

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

It's always sensible to use APIs in the way they were designed. If the docs say don't mutate your state, then you'd better not mutate your state.

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

Whilst setState()might be technically asynchronous, it's certainly not slow in any noticeable way. The component's render()function will be called in pretty short order.

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

One drawback of setting state directly is that React's lifecycle methods - shouldComponentUpdate(), componentWillUpdate(), componentDidUpdate()- depend on state transitions being called with setState(). If you change the state directly and call setState()with an empty object, you can no longer implement those methods.

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

Another is that it's just bad programming style. You're doing in two statements what you could be doing in one.

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

Moreover, there's no actual benefit here. In both cases, render()is not going to be triggered until after setState()(or forceUpdate()) is called.

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

You claim a need to do this without actually explaining what that need is. Perhaps you'd like to detail your problem a little more. There's probably a better solution.

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

It's best to work with the framework rather than against it.

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

UPDATE

更新

From the comments below:

从下面的评论:

The need is that I want use the changed hasSubmit in below.

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

OK, I understand now. If you need to immediately use the future state property, your best bet is just to store it in a local variable.

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

const hasSubmit = false;

this.setState({
  hasSubmit: hasSubmit
});

if (hasSubmit) { 
  // Code that will use `hasSubmit` ...

回答by wintvelt

If you want to change state and trigger a re-render by react:Use the second code.

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

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

Problems/ errors with first code:

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

  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

回答by Sany Liew

You should never ignore the documentation advice. At the time of writing, setState allow second argument which is a callback function when the setState and re-render had finished. Since you never provides us how your code gonna use hasSubmit value, I believe some other may find this useful when they want to make sure the hasSubmit had been changed.

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

回答by Aditya Singh

this.setStatemaintains the react component's life cycle and doesn't seem like mutating variables (even though internally it does mutate state). So the one way flow in react cycle is maintained without any side effects.

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

The caveat is with using this.setStatedoesn't work with constructors in ES6 classes. We need to use this.state =pattern rather than this.setStatein ES6 constructors

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

回答by Dmitriy

You should use this.forceUpdate()in first example to force update the state. For example:

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

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

But it is better to use this.setStatebecause it is init native check-state mecanizm of React engine which is better then force update.

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

If you just update any param of this.statedirectly without setStatereact render mecanizm will not know that some params of state is updated.

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