简体   繁体   English

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

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

I want to change the value for the hasSubmit key, like in the First Code section.我想更改hasSubmit键的值,就像在第一个代码部分一样。 I know this is not recommended.我知道不推荐这样做。 But the second code is asynchronous and I don't want to use the callback function of setState .但是第二个代码是异步的,我不想使用setState的回调函数。

  • What is the difference of this.state and setState ? this.statesetState什么区别?
  • Is there any way to change state value hasSubmit immediately?有没有办法立即更改状态值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. hasSubmit set false in getInitialState() . hasSubmitgetInitialState()设置为false
  2. hasSubmit will change to false when I click submit button.当我单击submit按钮时, hasSubmit将更改为false
  3. hasSubmit will change to true when submitted.提交时hasSubmit将更改为true

First click submit has no problem and hasSubmit will be set to true .第一次点击submit没有问题, hasSubmit将被设置为true

But second click submit will be wrong using the Second asynchronous code , because the hasSubmit is still true , while the First Code can resolve the problem.但是使用Second asynchronous code第二次点击submit会出错,因为hasSubmit仍然是true ,而First Code可以解决问题。

Here's what the React docs say:这是React 文档所说的:

NEVER mutate this.state directly, as calling setState() afterwards may replace the mutation you made.永远不要直接改变this.state ,因为之后调用 setState() 可能会替换你所做的改变。 Treat this.state as if it were immutable.将 this.state 视为不可变的。

setState() does not immediately mutate this.state but creates a pending state transition. setState()不会立即改变 this.state 而是创建一个挂起的状态转换。 Accessing this.state after calling this method can potentially return the existing value.调用此方法后访问this.state可能会返回现有值。

There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.无法保证对 setState 调用的同步操作,并且可能会批量调用以提高性能。 setState() will always trigger a re-render unless conditional rendering logic is implemented in shouldComponentUpdate() .除非在shouldComponentUpdate()实现了条件渲染逻辑,否则setState()将始终触发重新渲染。

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

It's always sensible to use APIs in the way they were designed.按照设计的方式使用 API 总是明智的。 If the docs say don't mutate your state, then you'd better not mutate your state.如果文档说不要改变你的状态,那么你最好不要改变你的状态。

Whilst setState() might be technically asynchronous, it's certainly not slow in any noticeable way.虽然setState()在技​​术上可能是异步的,但它肯定不会以任何明显的方式变慢。 The component's render() function will be called in pretty short order.组件的render()函数将在很短的时间内被调用。

One drawback of setting state directly is that React's lifecycle methods - shouldComponentUpdate() , componentWillUpdate() , componentDidUpdate() - depend on state transitions being called with setState() .直接设置状态的一个缺点是 React 的生命周期方法 - shouldComponentUpdate()componentWillUpdate()componentDidUpdate() - 依赖于使用setState()调用的状态转换。 If you change the state directly and call setState() with an empty object, you can no longer implement those methods.如果直接更改状态并使用空对象调用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` ...

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

this.setState maintains the react component's life cycle and doesn't seem like mutating variables (even though internally it does mutate state). this.setState维护了 react 组件的生命周期,并且看起来不像是在改变变量(即使在内部它确实改变了状态)。 So the one way flow in react cycle is maintained without any side effects.因此,反应循环中的单向流程保持不变,没有任何副作用。

The caveat is with using this.setState doesn't work with constructors in ES6 classes.需要注意的是,使用this.setState不适用于 ES6 类中的构造函数。 We need to use this.state = pattern rather than this.setState in ES6 constructors我们需要在 ES6 构造函数中使用this.state =模式而不是this.setState

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.在撰写本文时,setState 允许第二个参数,它是 setState 和重新渲染完成时的回调函数。 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.由于您从未向我们提供您的代码将如何使用 hasSubmit 值,我相信其他一些人在想要确保 hasSubmit 已被更改时可能会发现这很有用。

You should use this.forceUpdate() in first example to force update the state.您应该在第一个示例中使用this.forceUpdate()来强制更新状态。 For example:例如:

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

But it is better to use this.setState because 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.state directly without setState react render mecanizm will not know that some params of state is updated.如果你只是在没有setState下直接更新this.state任何参数, this.state渲染this.state将不知道状态的某些参数已更新。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM