From b582e3baca1f1238a0a5f3f8e5e8a1d1db4d1506 Mon Sep 17 00:00:00 2001 From: YuJian Date: Tue, 28 Jun 2022 17:54:23 +0800 Subject: [PATCH] vault backup: 2022-06-28 17:54:23 --- .../React 的深入探索 - beginWork.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/React 的深入探索/React 的流程解析 - Fiber 递归/React 的深入探索 - beginWork.md b/React 的深入探索/React 的流程解析 - Fiber 递归/React 的深入探索 - beginWork.md index 6f1ca0c..8a2a125 100644 --- a/React 的深入探索/React 的流程解析 - Fiber 递归/React 的深入探索 - beginWork.md +++ b/React 的深入探索/React 的流程解析 - Fiber 递归/React 的深入探索 - beginWork.md @@ -163,17 +163,20 @@ switch 中的 case 逻辑太多了,全部都写出来会让笔记显得特别 首先会执行 pushHostRootContext 函数,这个函数与 context 有关,暂且不谈 -然后会接着执行 +然后会接着执行 cloneUpdateQueue 方法 **cloneUpdateQueue** + 这个方法比较简单,会判断 current 和 workInProgress 中的 updateQueue 是否相同,如果相同会创建新的对象重复赋值以清除引用,这里是为了保证后续对 workInProgress 的操作不会影响到 current + ```javascript function cloneUpdateQueue(current, workInProgress) { var queue = workInProgress.updateQueue; var currentQueue = current.updateQueue; - // 对比更新队列 + // 用三等对比更新队列,如果为 true 表示 queue 还未清除引用 if (queue === currentQueue) { + // 清除引用 var clone = { baseState: currentQueue.baseState, firstBaseUpdate: currentQueue.firstBaseUpdate, @@ -181,11 +184,14 @@ function cloneUpdateQueue(current, workInProgress) { shared: currentQueue.shared, effects: currentQueue.effects }; + // 赋值 workInProgress.updateQueue = clone; } } ``` +从processUpdateQueue + ```javascript function updateHostRoot(current, workInProgress, renderLanes) { // context 相关 @@ -225,8 +231,6 @@ function updateHostRoot(current, workInProgress, renderLanes) { } ``` -updateHostRoot 函数中首先会执行 pushHostRootContext 方法,这个方法和 Context 相关,现在暂且不谈 -在 updateHostRoot 逻辑一开始,它会将 current 和 WorkInProgress 传递给 cloneUpdateQueue 这个函数,这个函数会将 Fiber 中的 queue 属性进行 clone,除非它们已经是 clone 之后的属性,那么具体是怎么做的判断是否是 clone 过的属性呢?其实很简单,它只是使用了 === 三个等于判断属性的引用是否相同,也就是说这个函数实际上做的是清除引用,保证在之后对 WorkInProgress 的操作不会影响到 current Fiber 树,判断两个 Fiber 树的 updateQueue 属性的引用完全相同,那么就会创建一个新的对象并重复赋值达到清除应用的目的,最后赋值给 WorkInProgress Fiber 节点 之后,再把 WorkInProgress Fiber 节点交给 processUpdateQueue 函数,这个函数主要是处理更新队列,在这里先不展开,TODO 再往后是一些针对服务端渲染的一些处理逻辑,服务端渲染也不是这次讨论的目的,也先跳过 最终调用 reconcileChildren 为 FIber 创建一个子 Fiber 节点并返回