ReactFiberReconciler
由于文件是线性结构,且较长,直接按功能进行线性分析。 (未导出的模块可能并非按源代码结构进行的布局)
一、作用
一、创建容器
创建容器,貌似是入口
信息
createFiberRoot()方法由 ReactFiberRoot#创建 Fiber 根 提实现
export function createContainer(
containerInfo: Container,
tag: RootTag,
hydrationCallbacks: null | SuspenseHydrationCallbacks,
isStrictMode: boolean,
// TODO: Remove `concurrentUpdatesByDefaultOverride`. It is now ignored.
// 待办:移除 `concurrentUpdatesByDefaultOverride`。它现在已被忽略。
concurrentUpdatesByDefaultOverride: null | boolean,
identifierPrefix: string,
onUncaughtError: (
error: mixed,
// errorInfo: { +componentStack?: ?string },
errorInfo: { componentStack?: string },
) => void,
onCaughtError: (
error: mixed,
errorInfo: {
// +componentStack?: ?string;
componentStack?: string;
// +errorBoundary?: component(...props: any),
errorBoundary?: Component;
},
) => void,
onRecoverableError: (
error: mixed,
// errorInfo: { +componentStack?: ?string },
errorInfo: { componentStack?: string },
) => void,
onDefaultTransitionIndicator: () => void | (() => void),
transitionCallbacks: null | TransitionTracingCallbacks,
): OpaqueRoot {
const hydrate = false;
const initialChildren = null;
const root = createFiberRoot(
containerInfo,
tag,
hydrate,
initialChildren,
hydrationCallbacks,
isStrictMode,
identifierPrefix,
null,
onUncaughtError,
onCaughtError,
onRecoverableError,
onDefaultTransitionIndicator,
transitionCallbacks,
);
registerDefaultIndicator(onDefaultTransitionIndicator);
return root;
}
三、 查找宿主实例
备注
getInstance()在 'shared/ReactInstanceMap' 实现findCurrentHostFiber()在 'ReactFiberTreeReflection' 中实现getPublicInstance()由构建环境提供
function findHostInstance(component: Object): PublicInstance | null {
// 获取实例(方法来自于 shared )
const fiber = getInstance(component);
// 获取的实例为空则抛出错误
if (fiber === undefined) {
if (typeof component.render === 'function') {
throw new Error('Unable to find node on an unmounted component.');
} else {
const keys = Object.keys(component).join(',');
throw new Error(
`Argument appears to not be a ReactComponent. Keys: ${keys}`,
);
}
}
// 查找当前宿主的 Fiber
const hostFiber = findCurrentHostFiber(fiber);
if (hostFiber === null) {
return null;
}
// 该方法由环境自行实现(在各平台各自的 renderer 中实现)
return getPublicInstance(hostFiber.stateNode);
}
四、查找宿主实例(带警告)
备注
getInstance()在 'shared/ReactInstanceMap' 实现findCurrentHostFiber在 'ReactFiberTreeReflection' 中实现getComponentNameFromFiber在 getComponentNameFromFiber 中实现runWithFiberInDEV在 ReactCurrentFiber#runWithFIberInDev 中实现
function findHostInstanceWithWarning(
component: Object,
methodName: string,
): PublicInstance | null {
if (__DEV__) {
// 该方法在 shared 中实现
const fiber = getInstance(component);
if (fiber === undefined) {
if (typeof component.render === 'function') {
throw new Error('Unable to find node on an unmounted component.');
} else {
const keys = Object.keys(component).join(',');
throw new Error(
`Argument appears to not be a ReactComponent. Keys: ${keys}`,
);
}
}
// 查找当前宿主 Fiber
const hostFiber = findCurrentHostFiber(fiber);
if (hostFiber === null) {
return null;
}
if (hostFiber.mode & StrictLegacyMode) {
// 文件 getComponentNameFromFiber 实现该方法
const componentName = getComponentNameFromFiber(fiber) || 'Component';
if (!didWarnAboutFindNodeInStrictMode[componentName]) {
didWarnAboutFindNodeInStrictMode[componentName] = true;
// 文件 ReactCurrentFiber 中实现该方法
runWithFiberInDEV(hostFiber, () => {
if (fiber.mode & StrictLegacyMode) {
console.error(
'%s is deprecated in StrictMode. ' +
'%s was passed an instance of %s which is inside StrictMode. ' +
'Instead, add a ref directly to the element you want to reference. ' +
'Learn more about using refs safely here: ' +
'https://react.dev/link/strict-mode-find-node',
methodName,
methodName,
componentName,
);
} else {
console.error(
'%s is deprecated in StrictMode. ' +
'%s was passed an instance of %s which renders StrictMode children. ' +
'Instead, add a ref directly to the element you want to reference. ' +
'Learn more about using refs safely here: ' +
'https://react.dev/link/strict-mode-find-node',
methodName,
methodName,
componentName,
);
}
});
}
}
// 该方法由环境自行实现(在各平台各自的 renderer 中实现)
return getPublicInstance(hostFiber.stateNode);
}
// 一: 查找宿主实例
return findHostInstance(component);
}
常数
1. 是否提示信息
// 是否警告关于嵌套更新
let didWarnAboutNestedUpdates: boolean;
// 是否警告在严格模式下使用 findNode
let didWarnAboutFindNodeInStrictMode: { [string]: boolean };
if (__DEV__) {
didWarnAboutNestedUpdates = false;
didWarnAboutFindNodeInStrictMode = {};
}
工具
1. 获取子树的上下文
- 如果参数为空,则返回一个空的上下文对象(
emptyContextObject) - 参数不为空,判定上写文是否是
class组件而做了一个兼容判定,返回子树的上下文
备注
getInstance()在 'shared/ReactInstanceMap' 实现findCurrentUnmaskedContext()在 "ReactFiberLegacyContext#findCurrentUnmaskedContext" 文件实现isLegacyContextProvider()在 'ReactFiberLegacyContext#isContextProvider' 实现processChildContext()方法在 'ReactFiberLegacyContext#processChildContext' 实现
function getContextForSubtree(
// 父组件 component(...props: any)
parentComponent?: Component,
): Object {
if (!parentComponent) {
return emptyContextObject;
}
const fiber = getInstance(parentComponent);
// 查找当前未屏蔽的上下文作为当前父元素的上下文
const parentContext = findCurrentUnmaskedContext(fiber);
if (fiber.tag === ClassComponent) {
const Component = fiber.type;
// 旧的遗留上下文提供者(即旧的 class 组件)
if (isLegacyContextProvider(Component)) {
// 返回兼容的父元素上下文
return processChildContext(fiber, Component, parentContext);
}
}
return parentContext;
}
转导
- 从 './ReactPortal' 转导了
createPortal()方法。 - 从 './ReactTestSelectors' 转导了测试用方法
- 从 './ReactFiberHooks' 转导了
startHostTransition()方法 - 从['./ReactFiberErrorLogger'] 转导了
defaultOnUncaughtError()、defaultOnCaughtError()、defaultOnRecoverableError()等方法