本次文件记录react库中相关API函数的使用及起源码实现。
createRef:createRef – React
createContext:createContext – React 中文文档
memo:memo – React 中文文档
startTransition:startTransition – React 中文文档
use:use – React 中文文档
lazy:lazy – React
createRef
React 中 createRef 函数的实现,主要用于 创建一个可变的 ref 对象,该对象在组件的整个生命周期内保持不变。createRef 主要用于 class 组件。
function createRef(): RefObject {
const refObject = {
current: null,
};
return refObject;
}
createContext
React 中 createContext 函数的实现,主要用于 创建上下文(Context)对象,实现跨组件层级的数据共享。
function createContext<T>(defaultValue: T): ReactContext<T> {
// 创建上下文对象
const context: ReactContext<T> = {
$$typeof: REACT_CONTEXT_TYPE,// 标记对象类型,用于 React 内部识别。
_currentValue: defaultValue,// 存储不同渲染阶段的上下文值
_currentValue2: defaultValue,// 存储不同渲染阶段的上下文值
_threadCount: 0,// 并发线程计数(用于并发模式下的状态追踪)。
// These are circular
Provider: (null: any),// 提供上下文的组件
Consumer: (null: any),// 消费上下文的组件
};
if (enableRenderableContext) {
// 新 API 模式(函数式)
context.Provider = context;
context.Consumer = {
$$typeof: REACT_CONSUMER_TYPE,
_context: context,
};
} else {
// 旧 API 模式(render prop)
(context: any).Provider = {
$$typeof: REACT_PROVIDER_TYPE,
_context: context,
};
(context: any).Consumer = context;
}
return context;
}
memo
memo 函数是 React 中用于创建记忆化组件的高阶函数,它的作用是对传入的组件进行包装,返回一个新的组件类型。这个新组件会对前后两次的 props 进行比较,如果 props 没有发生变化,React 就不会重新渲染该组件,从而避免不必要的渲染,提高性能。
function memo<Props>(
type: React$ElementType,
compare?: (oldProps: Props, newProps: Props) => boolean,
) {
// 创建新的元素类型对象
const elementType = {
$$typeof: REACT_MEMO_TYPE,
type,
compare: compare === undefined ? null : compare,
};
return elementType;
}
startTransition
React 中 过渡(Transition)机制 的核心实现,主要用于 将高优先级的紧急更新转换为低优先级的过渡更新。
function startTransition(
scope: () => void,
options?: StartTransitionOptions,
) {
// ReactSharedInternals.T 存储当前过渡上下文。
const prevTransition = ReactSharedInternals.T;
const currentTransition: BatchConfigTransition = {};
ReactSharedInternals.T = currentTransition;
// 支持过渡命名
if (enableTransitionTracing) {
if (options !== undefined && options.name !== undefined) {
currentTransition.name = options.name;
currentTransition.startTime = -1;
}
}
// 执行过渡回调(异步模式)
if (enableAsyncActions) {
try {
// 执行用户传入的回调,其中的 setState 会被标记为过渡更新。
const returnValue = scope();
const onStartTransitionFinish = ReactSharedInternals.S;
if (onStartTransitionFinish !== null) {
onStartTransitionFinish(currentTransition, returnValue);
}
// 处理异步返回值(Promise)
if (
typeof returnValue === 'object' &&
returnValue !== null &&
typeof returnValue.then === 'function'
) {
returnValue.then(noop, reportGlobalError);
}
} catch (error) {
// 捕获同步错误
reportGlobalError(error);
} finally {
// 检查过渡期间是否存在未完成的订阅(如 useEffect 未清理),并发出警告。
// warnAboutTransitionSubscriptions(prevTransition, currentTransition);
// 恢复旧上下文
ReactSharedInternals.T = prevTransition;
}
} else {
try {
scope();
} finally {
// warnAboutTransitionSubscriptions(prevTransition, currentTransition);
ReactSharedInternals.T = prevTransition;
}
}
}
type StartTransitionOptions = {
name?: string,
};
type BatchConfigTransition = {
name?: string,
startTime?: number,
_updatedFibers?: Set<Fiber>,
};
ReactSharedInternals.S
React 中 异步过渡(Async Transition) 机制的核心实现,主要用于 处理过渡回调返回的 Promise,并将其与过渡生命周期绑定。
ReactSharedInternals.S = function onStartTransitionFinishForReconciler(
transition: BatchConfigTransition,
returnValue: mixed,
) {
if (
enableAsyncActions &&
typeof returnValue === 'object' &&
returnValue !== null &&
typeof returnValue.then === 'function'
) {
// 启动计时器,记录过渡开始时间。
startAsyncTransitionTimer();
const thenable: Thenable<mixed> = (returnValue: any);
// 将过渡与 Promise 绑定,确保 Promise 状态变化能触发相应的过渡回调。
entangleAsyncAction(transition, thenable);
}
// 链式调用前一个回调
if (prevOnStartTransitionFinish !== null) {
prevOnStartTransitionFinish(transition, returnValue);
}
};
entangleAsyncAction
React 中 异步过渡(Async Transition) 机制的核心实现,主要用于 将异步操作(如 Promise)与过渡生命周期绑定,确保异步操作的完成状态能正确影响 UI 更新。
function entangleAsyncAction<S>(
transition: BatchConfigTransition,
thenable: Thenable<S>,
): Thenable<S> {
// 1.初始化异步操作上下文
// currentEntangledListeners:存储所有异步操作完成后的回调函数。
if (currentEntangledListeners === null) {
// There's no outer async action scope. Create a new one.
const entangledListeners = (currentEntangledListeners = []);
// 记录未完成的异步操作数量。
currentEntangledPendingCount = 0;
// 获取过渡车道(Lane),用于优先级调度。
currentEntangledLane = requestTransitionLane(transition);
// entangledThenable:自定义 Promise 接口,用于收集所有异步操作的完成回调。
const entangledThenable: Thenable<void> = {
status: 'pending',
value: undefined,
then(resolve: void => mixed) {
entangledListeners.push(resolve);
},
};
currentEntangledActionThenable = entangledThenable;
}
// 2.增加未完成计数并绑定回调
// 未完成异步操作数量加 1。
currentEntangledPendingCount++;
// 无论 Promise 成功或失败,都调用 pingEngtangledActionScope。
thenable.then(pingEngtangledActionScope, pingEngtangledActionScope);
return thenable;
}
pingEngtangledActionScope
React 中 异步过渡(Async Transition) 机制的核心回调函数,主要用于 在所有关联的异步操作完成后触发 UI 更新。
function pingEngtangledActionScope() {
// 当计数减为 0 时,表示所有异步操作已完成。
if (--currentEntangledPendingCount === 0) {
// if (enableProfilerTimer && enableComponentPerformanceTrack) {
// if (!hasScheduledTransitionWork()) {
// // 停止性能计时器(如果启用了性能追踪)。
// clearAsyncTransitionTimer();
// }
// }
if (currentEntangledListeners !== null) {
// All the actions have finished. Close the entangled async action scope
// and notify all the listeners.
if (currentEntangledActionThenable !== null) {
const fulfilledThenable: FulfilledThenable<void> = (currentEntangledActionThenable: any);
// 将其状态标记为 'fulfilled',表示所有操作已完成。
fulfilledThenable.status = 'fulfilled';
}
const listeners = currentEntangledListeners;
// 清空 currentEntangledListeners
currentEntangledListeners = null;
// 重置 currentEntangledLane(过渡优先级车道)
currentEntangledLane = NoLane;
currentEntangledActionThenable = null;
// 执行所有注册的回调函数(listeners),触发 React 的渲染流程。
for (let i = 0; i < listeners.length; i++) {
const listener = listeners[i];
listener();
}
}
}
}
let currentEntangledListeners: Array<() => mixed> | null = null;
use
lazy
lazy 函数用于创建懒加载组件。懒加载组件允许开发者在需要时才加载组件代码,而不是在应用启动时就加载所有组件代码,从而提高应用的加载性能。代码通过定义不同的加载状态常量,并使用一个闭包来管理组件的加载过程,实现了组件的懒加载功能。
函数参数说明:
- 参数
ctor:类型为() => Thenable<{default: T, ...}>,是一个返回Promise的函数。这个函数通常是动态导入组件的函数,例如() => import('./MyComponent')。
function lazy<T>(
ctor: () => Thenable<{default: T, ...}>,
): LazyComponent<T, Payload<T>> {
// 创建负载对象 payload
const payload: Payload<T> = {
//初始状态为 Uninitialized,表示组件还未开始加载。
_status: Uninitialized,
// 存储 ctor 函数,即动态导入组件的函数。
_result: ctor,
};
// 创建懒加载组件对象 lazyType
const lazyType: LazyComponent<T, Payload<T>> = {
// 值为 REACT_LAZY_TYPE,这是 React 用于标识懒加载组件的特殊属性。
$$typeof: REACT_LAZY_TYPE,
// 存储前面创建的 payload 对象,包含组件的加载状态和动态导入函数。
_payload: payload,
// 指向 lazyInitializer 函数,该函数用于初始化组件的加载过程。
_init: lazyInitializer,
};
// 返回懒加载组件对象
return lazyType;
}
type LazyComponent<T, P> = {
$$typeof: symbol | number,
_payload: P,
_init: (payload: P) => T,
_debugInfo?: null | ReactDebugInfo,
};
Promise 或异步操作的不同状态
Uninitialized:值为-1,表示组件还未开始加载,处于未初始化状态。Pending:值为0,表示组件正在加载中。Resolved:值为1,表示组件已经成功加载。Rejected:值为2,表示组件加载失败。
const Uninitialized = -1;
const Pending = 0;
const Resolved = 1;
const Rejected = 2;
lazyInitializer
lazyInitializer 函数是 React 中用于实现懒加载组件初始化逻辑的核心函数。它负责处理懒加载组件的加载过程,根据组件的不同加载状态(未初始化、加载中、已加载、加载失败)执行相应的操作,最终返回加载好的组件或者抛出加载错误。
function lazyInitializer<T>(payload: Payload<T>): T {
if (payload._status === Uninitialized) {// Uninitialized代表-1
// 从 payload._result 中获取动态导入组件的函数 ctor 并执行,得到一个 Promise 对象 thenable。
const ctor = payload._result;
const thenable = ctor();
// 处理 Promise 的结果
thenable.then(
// 当 thenable 成功解决时,检查 payload 的状态是否为 Pending(加载中)或 Uninitialized(未初始化)。如果是,则将 payload 的状态更新为 Resolved(已加载),并将加载的模块对象存储在 _result 中。
moduleObject => {
if (
(payload: Payload<T>)._status === Pending ||
payload._status === Uninitialized
) {
// Transition to the next state.
const resolved: ResolvedPayload<T> = (payload: any);
//代表组件加载完成
resolved._status = Resolved;
//执行结果
resolved._result = moduleObject;
}
},
// 当 thenable 被拒绝时,同样检查 payload 的状态。如果是 Pending 或 Uninitialized,则将 payload 的状态更新为 Rejected(加载失败),并将错误信息存储在 _result 中。
error => {
if ( //Pending代表0
(payload: Payload<T>)._status === Pending ||
payload._status === Uninitialized
) {
// Transition to the next state.
const rejected: RejectedPayload = (payload: any);
// 组件加载失败
rejected._status = Rejected;//Rejected代表2
rejected._result = error;
}
},
);
//如果在处理 Promise 后,payload 的状态仍然是 Uninitialized,则将其状态更新为 Pending(加载中),并将 thenable 存储在 _result 中。
if (payload._status === Uninitialized) {
const pending: PendingPayload = (payload: any);
pending._status = Pending;
pending._result = thenable;
}
}
// 返回加载结果
// 如果 payload._status 为 Resolved(已加载),则从 payload._result 中获取加载的模块对象,并返回其 default 属性,通常这就是懒加载的组件。
if (payload._status === Resolved) {//Resolved代表1
const moduleObject = payload._result;
return moduleObject.default;
} else {
// 抛出错误
throw payload._result;
}
}
453

被折叠的 条评论
为什么被折叠?



