优秀的编程知识分享平台

网站首页 > 技术文章 正文

谈谈react setState什么情况下异步或同步

nanyue 2024-08-05 19:51:52 技术文章 14 ℃

谈谈理解,不保证其准确性

setState 只在合成事件和钩子函数中是异步的,在原生事件和任务队列里都是同步的

一:什么是react合成事件和钩子函数

react自己封装的事件系统就是合成事件,用来代替原生事件,如jsx里的onClick,onChange等事件都是合成事件;

钩子函数就是didMonut,stateFromProps等

二:什么是原生事件和任务队列

原生事件指的是非react合成事件,如 document.querySelector().onclick 这种绑定事件的形式

任务队列就是setTimeout,promise then等

三:setState 的批量更新概念

只有异步才有批量更新。当更新的key是同一个值,setstate批量更新策略会进行覆盖,只取最后一次执行;当更新的key是不同值,那么会进行合并并更新

四:setState异步概念

setState的异步并不是说内部由异步代码实现,其实本身执行的过程和代码都是同步的,只是合成事件和钩子函数的调用顺序在dom更新之前,导致在合成事件和钩子函数中不能拿到更新后的值,形式了所谓的“异步”,当然可以通过setState(partialState, callback) 第二个参数 中的callback拿到更新后的结果。

React-dom源码版本16.4.1中:有个try{}finally{},合成事件和钩子函数代码块中的执行都是在try里,执行完毕才走到finally里performSyncWork方法,该方法执行完毕才会重新渲染dom

五:实例代码

constructor(props) {

super(props);

this.state = {val:0};

}

componentDidMount() {

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

console.log(this.state.val,1)

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

console.log(this.state.val,2)

new Promise((resolve) => {

resolve()

}).then(_ => {

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

console.log(this.state.val,3)

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

console.log(this.state.val,4)

})

}

打印出来的val分别是0,0,2,3

前两次打印是钩子函数异步批量更新,只执行后一次setState,此时console并不能获取到最新的,会显示0;任务队列promise里setState是同步的,更新完dom以后执行console,此时可以获取到最新的val值

最近发表
标签列表