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.
 
 

2.5 KiB

这个函数的任务是创建 WorkInProgress 树的 Fiber 节点,根据传入参数的判断是复用已有的 Fiber 节点或是创建新的 Fiber 节点

createWorkInProgress 在 Fiber 递归开始前和进入 Bailout 逻辑的时候都会被触发,React 为了提高性能会尽可能的复用 Fiber,如果当前的 current 节点已经存在一个链接的 WorkInProgress 节点,那么新创建的 WorkInProgress 就会基于这个已有的节点来创建。

逻辑开始会先判断传入的 Fiber 节点是否存在 alternate 属性。

// 函数接受两个参数:current 节点和节点的 props 属性
function createWorkInProgress(current, pendingProps) {
	var workInProgress = current.alternate;
	if (workInProgress === null) {
		......
	} else {
		......
	}
}

根据属性是否存在会进入不同的新 Fiber 创建逻辑:

创建新 Fiber 节点

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

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:

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 的逻辑就结束了。