反应中的setState增量和每个增量1有啥区别[重复]

Posted

技术标签:

【中文标题】反应中的setState增量和每个增量1有啥区别[重复]【英文标题】:What is the difference between setState increment and each increment 1 in react [duplicate]反应中的setState增量和每个增量1有什么区别[重复] 【发布时间】:2019-04-28 06:33:21 【问题描述】:
class App extends React.Component 
  constructor(props) 
    super(props);
    this.state = 
      num: 1
    
  
  componentDidMount() 
    this.setState(
      num: this.state.num+1
    );
    this.setState(
      num: this.state.num+1
    );
  
  render() 
    return (
      <div>
         this.state.num 
      </div>

    )
  

componentDidMount 中调用 setState 两次使用 +1 更新 num,但最终 num 为 2

class App extends React.Component 
  constructor(props) 
    super(props);
    this.state = 
      num: 1
    
  
  componentDidMount() 
    this.setState(
      num: ++this.state.num
    );
    this.setState(
      num: ++this.state.num
    );
  
  render() 
    return (
      <div>
         this.state.num 
      </div>

    )
  

setState 使用自增更新 num,但最终 num 为 3。

这两种方法有什么区别?以及如何理解 setState 是如何更新状态的?

谢谢

【问题讨论】:

阅读Why avoid increment (“++”) and decrement (“--”) operators in javascript? 及其答案,了解为什么像这样使用++ 通常是一个坏主意(或不是,取决于您阅读的答案)。 关于 React 如何使用setState,documentation does a pretty good job 您将两个问题合二为一。我已将其作为 duplicate 关闭,因为这里的主要问题是 setState 的使用,另一个更“次要”的问题与 JS 基础知识和 @ HereticMonkey 在第一条评论中提到了它。 【参考方案1】:

setState 是异步的,返回后 this.state 还没有改变:

this.setState(
  num: this.state.num+1 // this.state.num is 1, so the value here is 2
);
this.setState(
  num: this.state.num+1 // this.state.num is still 1, so the value is still 2
);

所以这和

this.setState(
  num: 2
);
this.setState(
  num: 2
);

但是,在您的第二个示例中,您正在改变 this.state.num 所以

this.setState(
  num: ++this.state.num // this.state.num is 2 after increment
);
this.setState(
  num: ++this.state.num // this.state.num is 3 after incrementing again
);

这实际上是一样的

this.setState(
  num: 2
);
this.setState(
  num: 3
);

一般来说,调用 setState 并根据 this.state 计算新值并不是一个好主意。如果要根据 state 中的当前值改变 state,请不要访问this.state! 相反,给setState一个回调:

setState(state => ( num: state.num + 1 )

考虑ReactJS docs中的这个例子:

例如,如果您 尝试在同一个项目中多次增加项目数量 循环,这将导致相当于:

Object.assign(
  previousState,
  quantity: state.quantity + 1,
  quantity: state.quantity + 1,
  ...
)

后续调用将覆盖之前调用的值 循环,所以数量只会增加一次。如果接下来 状态取决于当前状态,我们建议使用更新程序 函数形式,而不是:

this.setState((state) => 
  return quantity: state.quantity + 1;
);

【讨论】:

【参考方案2】:

setState 是异步的,所以你不能依赖当前状态来更新它。 请参考this文档,尤其是讨论类似示例的部分:

这种形式的 setState() 也是异步的,同一周期内的多次调用可能会被批处理在一起。例如,如果您尝试在同一个周期中多次增加一个项目数量,这将导致等价于:...等

【讨论】:

以上是关于反应中的setState增量和每个增量1有啥区别[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在反应中每 5 秒加 1 和 setState

反应:当我用后增量更改变量的状态时,程序中的值不同

增量式pid和位置式pid相比各有啥优缺点

ReactJS 中的 this.state 和 this.setstate 有啥区别?

完全备份、差异备份及增量备份

完全备份差异备份以及增量备份的区别