1 )概述
FunctionComponent
是引出调和子节点的过程2 )源码
定位到 packages/react-reconciler/src/ReactFiberBeginWork.js
的 beginWork 函数,在 beginWork 下面的 执行 switch case 中
// beginWork 函数中的截取部分
case FunctionComponent: {
// 这里的 type 就是 ReactElement 里面存储的 type 属性
// 这个 type 属性里面存储的就是 组件,如果是dom原生组件就是字符串
// 如果组件是 function component 就是一个方法,如果是 class component 它就是类
const Component = workInProgress.type;
// pendingProps 是新渲染的时候产生的 props,这个和调和子节点有关系
const unresolvedProps = workInProgress.pendingProps;
// 这个 resolvedProps 是和 Suspense 组件有关的,throw 的是一个 Promise 可能会resolve出一些东西
// 可以先默认 resolvedProps 就是上面的 unresolvedProps
const resolvedProps =
workInProgress.elementType === Component
? unresolvedProps
: resolveDefaultProps(Component, unresolvedProps);
return updateFunctionComponent(
current,
workInProgress,
Component,
resolvedProps,
renderExpirationTime,
);
}
进入到 updateFunctionComponent 方法
function updateFunctionComponent(
current,
workInProgress,
Component,
nextProps: any,
renderExpirationTime,
) {
// 获取两个 context 先跳过
const unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
const context = getMaskedContext(workInProgress, unmaskedContext);
let nextChildren;
prepareToReadContext(workInProgress, renderExpirationTime);
// 跳过 DEV 相关
if (__DEV__) {
ReactCurrentOwner.current = workInProgress;
ReactCurrentFiber.setCurrentPhase('render');
nextChildren = Component(nextProps, context);
ReactCurrentFiber.setCurrentPhase(null);
} else {
// 这里的 Component 就是组件的方法
// 调用 Component 方法的时候传入 nextProps, context 两个参数
// context 这个在 官网API文档中没有提及
// 可以在 function component 中获取到 child组件的 contextTypes 属性,也就是组件加上这个属性并配置props
// 组件内就可以获取上层传递过来的 context
nextChildren = Component(nextProps, context);
}
// React DevTools reads this flag.
//
workInProgress.effectTag |= PerformedWork;
reconcileChildren(
current,
workInProgress,
nextChildren,
renderExpirationTime,
);
// 这里 return 的是 child, 说明 在 reconcileChildren 很可能处理 child
return workInProgress.child;
}
workInProgress.effectTag |= PerformedWork;
这种操作