资讯专栏INFORMATION COLUMN

理解setState(),异步还是同步?

hedge_hog / 434人阅读

摘要:假设现在最后仍然会是,不是所以不能依赖来计算未来状态。原理可以参考这篇很简洁易懂的文章其他情景,如上面的情景,或这样用绑定函数脱离了的控制,不知道如何进行,就会是同步的。

state

state的存在是为了动态改变组件,比如根据不同的用户操作和网络请求,来重新渲染组件。

setState()是React给我们的一个API,用来改变或定义state。

setState()的批量操作(batching)

在一个事件handler函数中,不管setState()被调用多少次,他们也会在函数执行结束以后,被归结为一次重新渲染, 可以优化性能, 这个等到最后一起执行的行为被称为batching

所以在函数内的setState()是有序的,如果要更改同一个state key,最后被调用的总会覆盖之前的。

因为batching的存在,所以这样的代码会和期待有出入。

//假设现在this.state.value = 0;

function eventHandler(){
    this.setState({value:this.state.value + 1});
    this.setState({value:this.state.value + 1});
    this.setState({value:this.state.value + 1});
}

//最后this.state.value仍然会是1,不是3;

所以不能依赖this.state来计算未来状态。如果想实现这样的效果,应该传一个函数给setState。这个函数有两个参数,第一个为previous state,第二个为props。这里的例子和props无关,只需要第一个参数,所以要达到效果,代码是这样

// 假设 this.state = { value: 0 };

function eventHandler(){
    this.setState((state) => ({ value: state.value + 1}));
    this.setState((state) => ({ value: state.value + 1}));
    this.setState((state) => ({ value: state.value + 1}));
}

//现在this.state.value === 3;

到这里我们得到结论,setState是异步执行的。

如React文档所说:

"setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after 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."

所以当更新state,然后想打印state的时候,应该使用回调。

this.setState({key: val},()=>console.log(this.state));    
所以setState总是异步的,吗?

当setState()不在事件Handler函数中,如在使用ajax的时候,这种batching的异步表现又不会发生

promise.then(() => {
  // 不在事件函数中,所以setState立刻执行
  this.setState({a: true}); // 重新渲染 {a: true, b: false }
  this.setState({b: true}); // 重新渲染 {a: true, b: true }
});
同步异步要分情况来看: 1. React事件函数使用,像这样用最常用的形式绑定函数
constructor(props){
    ...
    this.onClick = this.onClick.bind(this);
}

onClick(){
    this.setState({key:val});
}

render(){
    return(
        
}

这里batching发生,异步表现,是因为这种常规情景下React “知道”什么时候退出该事件,什么时候进行Batch Update。原理可以参考这篇很简洁易懂的文章

2.其他情景,如上面的ajax情景,或这样用addEventListener绑定函数
componentDidMount(){
    document.querySelector("#btn").addEventListener("click,this.onClick);
}
    
    render(){
        return(
            
} }

脱离了React的控制,React不知道如何进行Batch Update,setState()就会是同步的。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/101984.html

相关文章

  • setState异步同步与进阶

    摘要:根本原因在于,并不是真正意义上的异步操作,它只是模拟了异步的行为。而合成事件和生命周期函数中,是受控制的,其会将设置为,从而走的是类似异步的那一套。总结此处总结是直接引用了只在合成事件和钩子函数中是异步的,在原生事件和中都是同步的。 如何使用setState 在 React 日常的使用中,一个很重要的点就是,不要直接去修改 state。例如:this.state.count = 1是无...

    widuu 评论0 收藏0
  • React 中 setState() 为什么是异步的?

    摘要:正文在回复中表示为什么是异步的,这并没有一个明显的答案,每种方案都有它的权衡。需要注意的是,异步更新是有可能实现这种设想的前提。 前言 不知道大家有没有过这个疑问,React 中 setState() 为什么是异步的?我一度认为 setState() 是同步的,知道它是异步的之后很是困惑,甚至期待 React 能出一个 setStateSync() 之类的 API。同样有此疑问的还有 ...

    anonymoussf 评论0 收藏0
  • React专题:react,redux以及react-redux常见一些面试题

    摘要:我们可以为元素添加属性然后在回调函数中接受该元素在树中的句柄,该值会作为回调函数的第一个参数返回。使用最常见的用法就是传入一个对象。单向数据流,比较有序,有便于管理,它随着视图库的开发而被概念化。 面试中问框架,经常会问到一些原理性的东西,明明一直在用,也知道怎么用, 但面试时却答不上来,也是挺尴尬的,就干脆把react相关的问题查了下资料,再按自己的理解整理了下这些答案。 reac...

    darcrand 评论0 收藏0
  • React-setState杂记

    摘要:简单的举下例子如等生命周期以及的事件即为异步更新,这里不显示具体代码。因为只有当父组件后才传给子组件,那么如果要变成同步的,就需要放弃。 前言 在看React的官方文档的时候, 发现了这么一句话,State Updates May Be Asynchronous,于是查询了一波资料, 最后归纳成以下3个问题 setState为什么要异步更新,它是怎么做的? setState什么时候会...

    yuxue 评论0 收藏0
  • 【React进阶系列】 setState机制

    摘要:的批量更新优化也是建立在异步合成事件钩子函数之上的,在原生事件和中不会批量更新,在异步中如果对同一个值进行多次,的批量更新策略会对其进行覆盖,取最后一次的执行,如果是同时多个不同的值,在更新时会对其进行合并批量更新。 api解析: setState(updater, [callback]) updater: 更新数据 FUNCTION/OBJECT callback: 更新成功后的回...

    Yuqi 评论0 收藏0

发表评论

0条评论

hedge_hog

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<