|
|
|
>这个函数的任务是创建 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 的逻辑就结束了。
|