欢迎光临散文网 会员登陆 & 注册

React是如何将数据变化渲染到页面的

2023-06-30 21:04 作者:小老虎Tigger  | 我要投稿

针对这个问题,我们需要对React有一个非常简单的宏观的认识。

React其实就是一个输入数据,然后根据数据产出页面的函数。

我们带着这个宏观的认识开始从一次点击事件开始观察react整个渲染的流程。

我们先创建一个最简单的react应用。

当我们点击一个dom节点时,我们可以从event对象中获取到当前事件发生的dom节点。而React中,我们给组件绑定一个onClick事件,其实事件并没有被真正的注册到dom上。React将大多数事件在整个应用初次挂载的时候都绑定到了根节点上,当真正的点击事件发生时,会先从event中拿到当前事件发生的dom,从dom中获取fiber对象,然后再一直沿父节点收集所有fiber上的onClick属性,收集完成后再遍历去执行。

 而从button中收集到的onClick就会被执行,setData其实就是useState返回的dispatchSetState函数,主要就是创建update,开启调度。

update中保存了优先级,payload/action,next等信息,最终会在beginWork中,调用函数组件获取子节点时,通过usState更新,这个时候useState返回的就是更新后的state。具体更新逻辑在updateReducer这个函数中。

开启调度是为了通过messageChannel异步发起react更新。简单来说,就是为了运行

等同步代码头执行完,通过postMessage进入到宏任务的task(performConcurrentWorkOnRoot/performSyncWorkOnRoot)将开始执行,先执行workLoop函数对整个fiber进行深度优先遍历,再执行commitRoot完成更新。

workLoop函数会循环调用performUnitOfWork函数。

先执行beginWork,根据对比更新的结果,给子节点打上增删移等标记。

在子节点为null时,再调用completeWork,completeWork将会判断HostComponent类型的组件,也就是实际的dom的节点,是否需要更新。需要的话,就打上更新标记。

completeWork还会将这些打了标记的fiber节点,添加到父节点的副作用队列中,这样在commit阶段,只需要从根节点就可以拿到全部需要处理的fiber节点,不用在此对fiber树进行遍历。

等整个fiber树都遍历完,就可以执行commitRoot函数,对打了标记的节点进行处理。commitRoot会在dom更改之前,之后调用不同的我们在组建中提供的勾子函数或者Effect Hooks。

我们主要看一下HostComponent,也就是真实dom在这个时候是如何更改的。因为前期已经对需要更改的节点都打上了update标记,所以会执行commitUpdate函数。

根据不同属性做不同处理,children其实也是一种属性。我们此处是h1的children更改了,所以会执行setTextContent函数。

children其实也是props


将新的value,更新到dom上。

这样,在点击完成后,react就将更改真正的同步到了页面上。

React是如何将数据变化渲染到页面的的评论 (共 条)

分享到微博请遵守国家法律