1
0
Fork 0
Obsidian 管理的个人笔记仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
2.5 KiB

>这个函数的任务是创建 WorkInProgress 树的 Fiber 节点,根据传入参数的判断是复用已有的 Fiber 节点或是创建新的 Fiber 节点
createWorkInProgress 在 Fiber 递归开始前和进入 Bailout 逻辑的时候都会被触发,React 为了提高性能会尽可能的复用 Fiber,如果当前的 current 节点已经存在一个链接的 WorkInProgress 节点,那么新创建的 WorkInProgress 就会基于这个已有的节点来创建。
逻辑开始会先判断传入的 Fiber 节点是否存在 alternate 属性。
```javascript
// 函数接受两个参数:current 节点和节点的 props 属性
function createWorkInProgress(current, pendingProps) {
var workInProgress = current.alternate;
if (workInProgress === null) {
......
} else {
......
}
}
```
根据属性是否存在会进入不同的新 Fiber 创建逻辑:
## 创建新 Fiber 节点
```javascript
workInProgress = createFiber(
current.tag,
pendingProps,
current.key,
current.mode
);
// 赋值同名参数
workInProgress.elementType = current.elementType;
workInProgress.type = current.type;
workInProgress.stateNode = current.stateNode;
// 通过 alternate 属性互相链接
workInProgress.alternate = current;
current.alternate = workInProgress;
```
可以看到 Fiber 的创建逻辑主要是调用了 createFiber 函数,而这个函数的逻辑也很简单:
### createFiber
```javascript
var createFiber = function (tag, pendingProps, key, mode) {
// 实例化一个初始的 Fiber 对象并返回
return new FiberNode(tag, pendingProps, key, mode);
};
```
主要任务就是实例化一个初始的 Fiber 对象并返回,然后在 createWorkInProgress 接下来的逻辑中会对一些存在 current 节点的属性进行复用
## 复用已有 Fiber 节点
从以上的判断逻辑出来会进入一大串 Fiber 属性赋值的逻辑,代码太长就不贴了,其中有一个 switch 语句,是为 Fiber type 属性赋值对应的 Component Type:
```javascript
switch (workInProgress.tag) {
case IndeterminateComponent:
case FunctionComponent:
case SimpleMemoComponent:
workInProgress.type = resolveFunctionForHotReloading(current.type);
break;
case ClassComponent:
workInProgress.type = resolveClassForHotReloading(current.type);
break;
case ForwardRef:
workInProgress.type = resolveForwardRefForHotReloading(current.type);
break;
}
```
最后返回创建好的 WorkInProgress Fiber 树,至此 createWorkInProgress 的逻辑就结束了。