React 中执行 setState 时怎么保证你取到的上一次state是正确的?

栏目: IOS · Android · 发布时间: 7年前

内容简介:setState 是 React 用于管理状态的一个特殊函数,我们在 React 中会经常使用到它,下面的场景你一定遇到过:上面这段代码,为什么呢?

setState 是 React 用于管理状态的一个特殊函数,我们在 React 中会经常使用到它,下面的场景你一定遇到过:

export class Todo extends React.Component{
  ... 
  increaseScore () {
    this.setState({count : this.state.count + 1});
    this.setState({count : this.state.count + 1});
  }
  ...
}
复制代码

上面这段代码, increaseScore 函数中希望将 count 这个状态的值在原来的基础上加1再加1,但是实际情况其实并不想你预期的那样,如果你在控制台把count的值打出来,会发现它只增加了1!

为什么呢?

setState 是异步的

setState 是异步的

看一下这个例子

class BadCounter extends React.Component{
  constructor(props){
    super(props);
    this.state = {count : 0} 
  }
  incrementCount=()=>{
    this.setState({count : this.state.count + 1}) 
    this.setState({count : this.state.count + 1})
  }
  render(){
    return <div>
              <button onClick={this.incrementCount}>+2</button>
              <div>{this.state.count}</div>
          </div>
  }
}

class GoodCounter extends React.Component{
  constructor(props){
    super(props);
    this.state = {count : 0} 
  }
  incrementCount=()=>{
   this.setState((prevState, props) => ({
      count: prevState.count + 1
    }));
   this.setState((prevState, props) => ({
      count: prevState.count + 1
    }));
  }
  render(){
    return <div>
              <button onClick={this.incrementCount}>+2</button>
              <div>{this.state.count}</div>
          </div>
  }
}
复制代码

在这个demo中,上下两个计数器都是希望实现点击后数+2,但是实际效果如下,只有第二个计数器达到了我们的预期:

React 中执行 setState 时怎么保证你取到的上一次state是正确的?

结合代码可以发现两个计数器的区别给 setState 传递的参数不一样

// 在错误示例中
this.setState({count : this.state.count + 1}) 
this.setState({count : this.state.count + 1}) 

// 在正确示例中
this.setState((prevState, props) => ({
  count: prevState.count + 1
}))
this.setState((prevState, props) => ({
  count: prevState.count + 1
}))
复制代码

查阅资料发现, 在多次调用 setState() 时,React 并不会同步处理这些 setState() 函数,而是做了一个“批处理”——如果使用对象作为参数传递给 setState ,React 会合并这些对象

而同样的情况下,当你给setState()传入一个函数时,这些函数将被放进一个队列,然后按调用顺序执行。

这里是react的核心成员 Dan Abramov 对 setState 为什么是异步的解释

总结

连续多次执行 setState 操作的情况是很常见的,下一次你如果在 setState 时需要用到 this.state 的时候要切记,在 setState 中利用函数操作来取得上一次的 state 值才是正确的做法!


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

创投42章经

创投42章经

曲凯 / 中信出版集团 / 2018-10-20 / 58.00

《创投42章经》是拥有百万粉丝的微信公众号“42章经”的精选文章合集,全书共分为心法、内功、招式和江湖传奇四部分。 在心法部分,读者可以学到一些创业与投资的底层思维方式;在内功部分,读者可以了解到,投资人看待一家公司经营状况的标准;在招式部分,读者可以看到作者作为一名资深投资人和睿智的观察者,对过去几年主要的公司、模式以及风口的判断;最后的江湖传奇部分,作者通过一些故事,帮助读者更好地理解当......一起来看看 《创投42章经》 这本书的介绍吧!

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具