Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

react 的两个主要阶段:render阶段和commit阶段 #16

Open
mbaxszy7 opened this issue Jun 26, 2020 · 0 comments
Open

react 的两个主要阶段:render阶段和commit阶段 #16

mbaxszy7 opened this issue Jun 26, 2020 · 0 comments
Labels

Comments

@mbaxszy7
Copy link
Owner

mbaxszy7 commented Jun 26, 2020

先来看一下这张图
image
图片来自https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

图中介绍了React 16.4以后的生命周期函数的执行时机,牵扯到了React 的两个主要阶段:render阶段和commit阶段。下面来简单说一下这两个阶段React做了什么事。

render阶段

在render阶段,React将更新应用于通过setState或render方法触发的组件,并确定需要在用户屏幕上做哪些更新--哪些节点需要插入,更新或删除,哪些组件需要调用其生命周期方法。最终的这些更新信息被保存在一个叫effect list的fiber 节点树上(关于fiber的内容,在这篇文章中有简述react中的fiber)。当然,在首次渲染时,React不需要产生任何更新信息,而是会给每个从render方法返回的element生成一个fiber节点,最终生成一个fiber节点树, 后续的更新也是复用了这棵fiber树。

在上图中, render阶段被标记为纯的、没有副作用的,可能会被React暂停、终止或者重新执行。也就是说,React会根据产生的任务的优先级,安排任务的调度(schedule)。利用类似requestIdleCallback的原理在浏览器空闲阶段进行更新计算,而不会阻塞动画,事件等的执行。

commit阶段

在这个阶段时,React内部会有三个fiber树:

current fiber tree: 在首次渲染时,React不需要产生任何更新信息,而是会给每个从render方法返回的element生成一个fiber节点,最终生成一个fiber节点树, 后续的更新也是复用了这棵fiber树。

workInProgress fiber tree: 
所有的更新计算工作都在workInProgress tree的fiber上执行。当React 遍历current fiber tree时,它为每个current fiber 创建一个替代(alternate)节点,这样的alternate节点构成了workInProgress tree

effect list fiber tree: workInProgress fiber tree 的子树,这个树的作用串联了标记具有更新的节点

commit阶段会遍历effect list,把所有更新都commit到DOM树上。具体的,首先会有一个pre-commit阶段,主要是执行getSnapshotBeforeUpdate方法,可以获取当前DOM的快照(snap)。然后给需要卸载的组件执行componentWillUnmount方法。接着会把current fiber tree 替换为workInProgress fiber tree。最后执行DOM的插入、更新和删除,给更新的组件执行componentDidUpdate,给插入的组件执行componentDidMount。

重点要注意的是,这一阶段是同步执行的,不能中止。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant