这一把子彻底搞懂 setState 原理

开发 前端
在 setState 的调用中,有一个合成事件起到了关键性的作用。接下来,我们先去搞清楚这个小可爱,再来看具体的 setState 的代码实现。

 [[418361]]

本文转载自微信公众号「勾勾的前端世界」,作者西岭。转载本文请联系勾勾的前端世界公众号。

这上一篇中,我们基本搞清楚了原理流程,那具体的代码是如何实现的呢?

在 setState 的调用中,有一个合成事件起到了关键性的作用。接下来,我们先去搞清楚这个小可爱,再来看具体的 setState 的代码实现。

合成事件

首先明确定义,在 React 中为元素添加的事件被叫做合成事件。

合成事件的好处有两个:

一是屏蔽了浏览器之间关于事件处理的兼容性问题,为合成事件对象内部提供了统一的 API;

二是性能的提升, 事件都被委托给 document 。

React 并不会将事件添加到真正的 DOM 元素身上,它会将所有事件委托给 document 执行。如下图所示:

React 会在拥有事件的 DOM 对象身上添加一个 store 对象,在 store 对象中存储事件名称及事件处理函数,然后通过 document 分发事件。

当事件被触发后,通过获取事件源对象,查看事件源对象中是否存在 store 对象,获取 store 对象中事件处理函数,执行事件处理函数。

合成事件的事件对象在使用完成以后会被销毁。我长得帅,所以,我写了一段模拟性的代码,你看不看就随意了:

代码的注释中说的已经非常清楚了,爱看不看吧,就这样……

setState 实现原理

接着,我们再把上面的图拿出来,我分为了四段,进行了具体的梳理。先看图,再看字,最后上代码?

1、当 setState 方法被调用后,方法会将状态传递给组件更新器,让组件更新器将状态临时存储起来。每个组件都会有自己的组件更新器,当需要更新组件时调用组件更新器。

2、状态临时保存完成后判断当前是否为批量更新模式,如果是,将组件更新器添加到更新队列中;如果不是,直接更新组件。

批量更新模式是如何设置的:当触发合成事件时, 在事件处理函数执行之前,会先将批量更新模式设置为 true,然后执行事件处理函数收集状态。当事件处理函数执行完成后,执行批量更新操作,即从更新队列中获取组件更新器并调用。组件更新器调用完成后再将批量更新模式设置为 false。

3、更新组件时,先判断是否有状态需要更新,如果有就先计算最新状态,将得出的最新状态重新设置给组件。

计算状态时,如果状态是函数类型,调用函数传入当前状态,返回最新状态。如果状态是对象类型,使用对象状态覆盖原有状态。

4、组件状态计算完成后,通过调用组件内部的 render 方法获取新的 VirtualDOM,再通过 DOM 对象获取旧的虚拟 DOM,然后调用 diff 方法进行比对,对比完成后将差异更新到真实 DOM 对象中。

下面的代码,就是配合前面的流程图和文字描述实现的具体代码了。我看你也挺聪明的,所以加了非常详细的注释,就是为了遏制你的智力增长,如果还看不懂,那就算了吧,建议你去和娜塔莎抢婚,单身程序员这条路可能不适合你哟 (●'?'●)。

好了,就到这里吧。没想到你竟然真的没看代码,就知道往下拖进度条,哎,放弃吧,翠花是娜塔莎的,不可以插足!

当然,如果能点赞,我可以考虑送你一只翠花┗|`O′|┛。

 

责任编辑:武晓燕 来源: 勾勾的前端世界
相关推荐

2021-10-09 19:05:06

channelGo原理

2021-07-08 10:08:03

DvaJS前端Dva

2021-07-03 08:59:49

动态代理JDK

2023-10-18 10:55:55

HashMap

2019-11-08 16:05:54

Promise前端链式调用

2021-10-11 11:58:41

Channel原理recvq

2023-05-29 08:12:38

2021-08-29 08:14:30

GPU CSS gpu

2022-08-26 13:24:03

version源码sources

2022-04-24 11:06:54

SpringBootjar代码

2021-07-16 11:35:20

Java线程池代码

2019-07-23 08:55:46

Base64编码底层

2024-10-15 17:12:38

代码父子线程开源

2020-12-07 06:19:50

监控前端用户

2020-03-02 17:04:47

戴尔

2021-06-30 08:45:02

内存管理面试

2022-06-07 10:13:22

前端沙箱对象

2020-03-18 14:00:47

MySQL分区数据库

2021-07-21 05:24:32

EventBus3.0Android单例模式

2021-02-01 11:30:13

React前端调度
点赞
收藏

51CTO技术栈公众号