美文网首页
react setState源码浅析

react setState源码浅析

作者: IT_cool | 来源:发表于2020-07-12 21:27 被阅读0次

本篇文章主要是结合着react组件的生命周期来探究setState实现的原理,在学习一种新的框架前,我们应当首先比较他与之前的框架.比如结合着之前学习的angular或者vue,我们都知道他们有着共同点数据驱动视图更新,那么数据驱动视图的更新,核心点在于数据变化的监听,数据变化是表象,通过监听到数据变化,再把数据映射到操作dom或者虚拟dom上,最终呈现在视图上,同理react中通过setState或者改变props来触发组件更新.

对于视图更新,我们无法避免要知道浏览器event loop机制,宏任务/微任务概念,js单线程(h5 web worker暂时不提), 浏览器多线程以及各线程之间的关系,有了这些基础,对于下面的知识点会更容易理解.

react生命周期,相信大家都不会陌生,这里我就简单提一下,主要分为以下三个阶段:

1.创建阶段: constructor/componentWillMount/render/componentDidMount

2.更新阶段:componentWillReceiveProps/shouldComponentUpdate/componentWillUpdate/render/componentDidUpdate

3.销毁阶段:componentWillUnmount

react中操作setState我们可以大致分为两类:

a.原生事件(onclick/onchange), http请求, setTimeout/setInterval, promise, other(其他微任务操作)

b.组件生命周期创建阶段, react合成事件(onClick/onChange) ps:这类属于react可控

通过分析源码我们可以发现,a类相同点,每次setState后,就会执行enqueueUpdate,这时检测到批量更新策略的isBatchingUpdates为false,就执行ReactDefaultBatchingStrategy的batchedUpdates方法并且把enqueueUpdate做为回调函数传递, 接着就是维护enqueueUpdate,把新set的state加入到队列中,这个时候dirtyComponent执行push操作加入该组件.

通过分析源码我们可以发现,b类中在组件创建阶段,创建事务对象,后续操作基于此事务操作,b类相同点,在本次event loop中,,然后会先执行ReactDefaultBatchingStrategy的batchedUpdates方法,设置isBatchingUpdates为true,注意此变量值,每次event loop的开始时候都为false,每次event loop结束的时候,设置为false,此变量在每次event loop中变化情况如下:

isBatchingUpdates: false -> true -> false

执行transaction.perform,然后init事务相关配置,开始执行setState,接着就是维护enqueueUpdate,把新set的state加入到队列中,这个时候dirtyComponent执行push操作加入该组件.

注意在事务执行过程中,wrappers数组中包含的下方4个wrapper:

FLUSH_BATCHED_UPDATES //init设置emptyFuction, close方法调用了flushBatchedUpdates在下面三个wrapper执行之前,flushBatchedUpdates在组件创建阶段时,调用mountComponentIntoNode触发更新,然后会等到更新阶段执行完后再执行, 其他情况下flushBatchedUpdates会在更新阶段前执行,通过调用runBatchedUpdates触发更新

RESET_BATCHED_UPDATES //init设置emptyFuction, close方法用于设置批量更新策略ReactDefaultBatchingStrategy.isBatchingUpdates为false, 此方法在4个wrapper的close方法中最后执行

NESTED_UPDATES //init函数设置dirtyComponent长度, close函数分为当在componentDidUpdate中setState case,或者 清空dirtyComponent(大多数情况下属于这种) 此close方法在 UPDATE_QUEUEING的close方法之前

UPDATE_QUEUEING //init重新设置setState的callback queue, close函数触发执行callback queue

总结: 就是在组件创建时期或者react合成事件中, 多次setState(不包含a类中操作setState),属于一次事务中,会进行合并批量更新视图,如果在a类中多次setState,每次setState都属于一次事务中,并且每个setState后的程序并不会立刻执行,需要等到setState执行完,此执行完代表着以下过程全部执行完shouldComponentUpdate/componentWillUpdate/render/componentDidUpdate,此时视图已经基于第一次setState后更新完成,接着再执行第一个setState后的程序,同理第二个setState执行逻辑同上,直到所有同步代码执行完.单纯通过我的简单文字描述,理解起来会比较困难,需要结合源码debug,制作demo才能看的更清晰.附件为demo和主要源码截图,希望对大家有所帮助.

附件链接:https://pan.baidu.com/s/1eLQm2CIv4ID4M_QX8MLd-g, 提取码: 9kcy 源码链接

相关文章

网友评论

      本文标题:react setState源码浅析

      本文链接:https://www.haomeiwen.com/subject/zsbncktx.html