2025-05-14 日报 Day186

2025-05-14 日报 Day186

Yuyang 前端小白🥬

今日的鸡汤

这世上,有一条路不能选择,那就是放弃的路;有一条路不能拒绝,那就是成长的路。新时代要有新作为,每个人都是一种色彩,都是“不一样的烟火”。

今日学习内容

1、https://www.youtube.com/watch?v=EVFZazcxAbo&t=4112s

今日笔记

ReactDOM.render时如何串联渲染链路的

image-20250706170744519

![image-20250706170817557](../../../../../Library/Application Support/typora-user-images/image-20250706170817557.png)

performSyncWorkOnRoot开启的是我们反复强调的render阶段
而commitRoot方法开启的则是真实DOM的渲染过程(Commit阶段)

ReactDOM.render的初始化阶段

image-20250706171028941

构建基本实体

调用链路

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
return legacyRenderSubtreeIntoContainer(null,element,container,false,callback);

||
||


function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback){
// container对应的是我们传入的真实DOM对象
var root = container._reactRootContainer;
// 初始化fiberRoot对象
var fiberRoot;

// DOM对象本身不存在__reactRootContainer属性,因此Root为空
if (!root) {
// 若root为空,则初始化__reactRootContainer
root = container._reactRootContainer = legacyCreateRootFromDOMContainer(
container,
forceHydrate,
);
fiberRoot = root._internalRoot;

// 这里处理ReactDOM.render入参的回调函数
if(typeof callback === 'function'){
// 将回调函数存储在fiberRoot对象的callback属性中
var originalCallback = callback;
callback = function() {
var instance = getPublicRootInstance(fiberRoot);
originalCallback.call(instance);
};
}

// 进入unbatchedUpdate方法
unbatchedUpdates(function() {
updateContainer(
children,
fiberRoot,
parentComponent,
callback,
);
});
} else {

// else逻辑处理非首次渲染的情况(即更新),其逻辑除了跳过初始化工作,与楼上基本一致
// 如果已经存在fiberRoot对象,则获取它
fiberRoot = root._internalRoot;

if(typeof callback === 'function') {
var _originalCallback = callback;

callback = function() {
var instance = getPublicRootInstance(fiberRoot);

_originalCallback.call(instance);
};
}

updateContainer(children, fiberRoot, parentComponent, callback);
}
return getPublicRootInstance(fiberRoot);
}

image-20250706191510458

workInProgress
一颗current树,一颗workInProgress树

flag/effectTag

  • Placement
  • Update
  • Deletion
  • Passive
  • Layout

image-20250706200506070

image-20250706200526829

image-20250706201130701

completeWork

completeWork的工作内容:负责处理Fiber节点到DOM节点的映射逻辑

completeWork内部有3个关键动作:

  • 创建DOM节点(CreateInstance)
  • 讲DOM节点插入到DOM树中(AppendAllChildren)
  • 为DOM节点设置属性(FinalizeInitialChildren)

创建好的DOM节点会被赋值给workInProgress节点的stateNode属性

将DOM节点插入到DOM树中的操作是通过appendAllChildren函数来完成的

如果执行appendAllChildren 时,父级的DOM 节点还不存在怎么办?

比如h1 节点作为第一个进入 completeWork 的节点,它的父节点div对应的 DOM 就尚不存在。其实不存在也没关系,反正 h1DOM 节点被创建后,会作为h1 Fiber 节点的stateNode 属性存在

completeUnitOfWork–开启收集EffectList的“大循环”

  • 针对传入的当前节点,调用completeWork
  • 将当前节点的副作用链插入到其父节点对应的副作用链中
  • 以当前节点为起点,循环遍历其兄弟节点及其父节点
此页目录
2025-05-14 日报 Day186