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