跳到主要内容

React DOM client fiber

一、作用

二、导出的常量

1. 同步刷新

备注
const flushSync: typeof flushSyncIsomorphic = disableLegacyMode
? flushSyncIsomorphic
: flushSyncFromReconciler;

三、创建门户

备注
function createPortal(
children: ReactNodeList,
container: Element | DocumentFragment,
key: ?string = null,
): React$Portal {
if (!isValidContainer(container)) {
throw new Error('Target container is not a DOM element.');
}

// TODO: pass ReactDOM portal implementation as third argument
// 待办事项:将 ReactDOM portal 实现作为第三个参数传递
return createPortalImpl(children, container, null, key);
}

四、不稳定的批量更新

function unstable_batchedUpdates<A, R>(fn: (a: A) => R, a: A): R {
// batchedUpdates was a legacy mode feature that is a no-op outside of
// legacy mode. In 19, we made it an actual no-op, but we're keeping it
// for now since there may be libraries that still include it.
// batchedUpdates 是一个遗留模式功能,在遗留模式之外无效。在 19 版本中,我们将其实际
// 变为无操作,但我们暂时保留它,因为可能还有一些库仍然包含它。
return fn(a);
}

五、常量

1. 找到开发者工具

备注

源码中 150 - 177 行

const foundDevTools = injectIntoDevTools();

if (__DEV__) {
if (!foundDevTools && canUseDOM && window.top === window.self) {
// If we're in Chrome or Firefox, provide a download link if not installed.
// 如果我们使用的是 Chrome 或 Firefox,如果未安装,则提供下载链接。
if (
(navigator.userAgent.indexOf('Chrome') > -1 &&
navigator.userAgent.indexOf('Edge') === -1) ||
navigator.userAgent.indexOf('Firefox') > -1
) {
const protocol = window.location.protocol;
// Don't warn in exotic cases like chrome-extension://.
// 不要在像 chrome-extension:// 这样的特殊情况下发出警告。
if (/^(https?|file):$/.test(protocol)) {
console.info(
'%cDownload the React DevTools ' +
'for a better development experience: ' +
'https://react.dev/link/react-devtools' +
(protocol === 'file:'
? '\nYou might need to use a local HTTP server (instead of file://): ' +
'https://react.dev/link/react-devtools-faq'
: ''),
'font-weight:bold',
);
}
}
}
}

六、工具

1. 校验 React 版本

在代码顶端执行了全局副作用 ensureCorrectIsomorphicReactVersion() 及校验了当前环境版本对 Map/Set 的支持情况。

ensureCorrectIsomorphicReactVersion();

if (__DEV__) {
if (
typeof Map !== 'function' ||
Map.prototype == null ||
typeof Map.prototype.forEach !== 'function' ||
typeof Set !== 'function' ||
Set.prototype == null ||
typeof Set.prototype.clear !== 'function' ||
typeof Set.prototype.forEach !== 'function'
) {
console.error(
'React depends on Map and Set built-in types. Make sure that you load a ' +
'polyfill in older browsers. https://react.dev/link/react-polyfills',
);
}
}

2. 从协调器同步刷新

备注
// Overload the definition to the two valid signatures.
// 重载定义以匹配两个有效的签名。
// Warning, this opts-out of checking the function body.
// 警告,这将放弃对函数体的检查。
declare function flushSyncFromReconciler<R>(fn: () => R): R;
declare function flushSyncFromReconciler(): void;
function flushSyncFromReconciler<R>(fn: (() => R) | void): R | void {
if (__DEV__) {
if (isAlreadyRendering()) {
console.error(
'flushSync was called from inside a lifecycle method. React cannot ' +
'flush when React is already rendering. Consider moving this call to ' +
'a scheduler task or micro task.',
);
}
}
return flushSyncWithoutWarningIfAlreadyRendering(fn);
}

3. 查找 DOM 节点

嗯,副作用

备注
function findDOMNode(
componentOrElement: component(...props: any),
): null | Element | Text {
return findHostInstance(componentOrElement);
}

// Expose findDOMNode on internals
// 在内部暴露 findDOMNode
Internals.findDOMNode = findDOMNode;

4. 共享事件

备注
// Keep in sync with ReactTestUtils.js.
// This is an array for better minification.
// 与 ReactTestUtils.js 保持同步。
// 这是一个用于更好压缩的数组。
Internals.Events /* Events */ = [
getInstanceFromNode,
getNodeFromInstance,
getFiberCurrentPropsFromNode,
enqueueStateRestore,
restoreStateIfNeeded,
unstable_batchedUpdates,
];

七、转导