react同步请求_react中setState是同步还是异步的

2019-06-04 10:28:36

我们都知道,React框架是由数据来驱动视图变化的,基于状态的管理实现对组件的管理,也就是组件当中的state,通过setState方法来修改当前组件的state,以达到视图的变化。

我们先来看一段代码:

class Example extends React.Component {

constructor() {

super();

this.state = {

val: 0

};

}

componentDidMount() {

this.setState({val: this.state.val + 1});

console.log(this.state.val); // 第 1 次 log

this.setState({val: this.state.val + 1});

console.log(this.state.val); // 第 2 次 log

setTimeout(() => {

this.setState({val: this.state.val + 1});

console.log(this.state.val); // 第 3 次 log

this.setState({val: this.state.val + 1});

console.log(this.state.val); // 第 4 次 log

}, 0);

}

render() {

return null;

}

};

当组件创建完成之后,其输出结果正常情况应该是:0 0 2 3。看到这里很多人会感到不理解,做过一段时间react开发的都应该清楚setState之后直接输出state值是不会改变的,但是为什么setTimeout中的setState就可以呢?下面我们来看一下。

setState的批量更新

有很多人说setState是异步更新的,我觉得这种说法是不准确的,严格来讲setState应该属于是批量更新。setState 通过一个队列机制来实现 state 更新,当执行 setState() 时,会将需要更新的 state 浅合并后放入 状态队列,而不会立即更新 state,队列机制可以高效的批量更新 state。而如果不通过setState,直接修改this.state 的值,则不会放入状态队列,当下一次调用 setState 对状态队列进行合并时,之前对 this.state 的修改将会被忽略,造成无法预知的错误。

大部分情况下我们写setState会直接将需要修改的状态当做参数传入,其实setStae的参数是这样的:

setState(nextState,callback);

在 setState 官方文档中介绍:将 nextState 浅合并到当前 state。这是在事件处理函数和服务器请求回调函数中触发 UI 更新的主要方法。不保证 setState 调用会同步执行,考虑到性能问题,可能会对多次调用作批处理。

在其参数后面的回调函数中其实我们是可以获取到更新之后的state,从这一点来看表面上类似于异步执行。

setState批量更新节点

在React的setState函数实现中,会根据一个变量 isBatchingUpdate 来判断是直接同步更新this.state还是放到队列中异步更新 。React使用了事务的机制,React的每个生命周期和合成事件都处在一个大的事务当中。在事务的前置钩子中调用batchedUpdates方法修改isBatchingUpdates变量为true,在后置钩子中将变量置为false。原生绑定事件和setTimeout异步的函数没有进入到React的事务当中,或者当他们执行时,刚刚的事务已近结束了,后置钩子触发了,所以此时的setState会直接进入非批量更新模式,表现在我们看来成为了同步SetState。

综上来说我们可以简单理解为,在当前的生命周期中,setState为异步批量更新,在异步函数中,执行的是同步更新的方式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值