跳到主要内容

非遗留上下文

一、作用

二、重置上下文依赖

export function resetContextDependencies(): void {
// This is called right before React yields execution, to ensure `readContext`
// cannot be called outside the render phase.

// 这会在 React 让出执行权之前调用,以确保 `readContext`
// 不会在渲染阶段之外被调用。
currentlyRenderingFiber = null;
lastContextDependency = null;
if (__DEV__) {
isDisallowedContextReadInDEV = false;
}
}

三、在开发环境中读取不允许的上下文

export function enterDisallowedContextReadInDEV(): void {
if (__DEV__) {
isDisallowedContextReadInDEV = true;
}
}

四、在开发环境中读取不允许的上下文退出

export function exitDisallowedContextReadInDEV(): void {
if (__DEV__) {
isDisallowedContextReadInDEV = false;
}
}

五、推送提供者

export function pushProvider<T>(
providerFiber: Fiber,
context: ReactContext<T>,
nextValue: T,
): void {
if (isPrimaryRenderer) {
push(valueCursor, context._currentValue, providerFiber);

context._currentValue = nextValue;
if (__DEV__) {
push(rendererCursorDEV, context._currentRenderer, providerFiber);

if (
context._currentRenderer !== undefined &&
context._currentRenderer !== null &&
context._currentRenderer !== rendererSigil
) {
console.error(
'Detected multiple renderers concurrently rendering the ' +
'same context provider. This is currently unsupported.',
);
}
context._currentRenderer = rendererSigil;
}
} else {
push(valueCursor, context._currentValue2, providerFiber);

context._currentValue2 = nextValue;
if (__DEV__) {
push(renderer2CursorDEV, context._currentRenderer2, providerFiber);

if (
context._currentRenderer2 !== undefined &&
context._currentRenderer2 !== null &&
context._currentRenderer2 !== rendererSigil
) {
console.error(
'Detected multiple renderers concurrently rendering the ' +
'same context provider. This is currently unsupported.',
);
}
context._currentRenderer2 = rendererSigil;
}
}
}

六、弹出提供者

export function popProvider(
context: ReactContext<any>,
providerFiber: Fiber,
): void {
const currentValue = valueCursor.current;

if (isPrimaryRenderer) {
context._currentValue = currentValue;
if (__DEV__) {
const currentRenderer = rendererCursorDEV.current;
pop(rendererCursorDEV, providerFiber);
context._currentRenderer = currentRenderer;
}
} else {
context._currentValue2 = currentValue;
if (__DEV__) {
const currentRenderer2 = renderer2CursorDEV.current;
pop(renderer2CursorDEV, providerFiber);
context._currentRenderer2 = currentRenderer2;
}
}

pop(valueCursor, providerFiber);
}

七、在父路径上调度上下文工作

备注
export function scheduleContextWorkOnParentPath(
parent: Fiber | null,
renderLanes: Lanes,
propagationRoot: Fiber,
) {
// Update the child lanes of all the ancestors, including the alternates.
// 更新所有祖先的 Lane ,包括备用 Lane。
let node = parent;
while (node !== null) {
const alternate = node.alternate;
if (!isSubsetOfLanes(node.childLanes, renderLanes)) {
node.childLanes = mergeLanes(node.childLanes, renderLanes);
if (alternate !== null) {
alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes);
}
} else if (
alternate !== null &&
!isSubsetOfLanes(alternate.childLanes, renderLanes)
) {
alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes);
} else {
// Neither alternate was updated.
// Normally, this would mean that the rest of the
// ancestor path already has sufficient priority.
// However, this is not necessarily true inside offscreen
// or fallback trees because childLanes may be inconsistent
// with the surroundings. This is why we continue the loop.
//
// 两个备用版本都没有更新。
// 通常,这意味着其余的祖先路径已经有足够的优先级。
// 然而,在屏幕外或备用树中情况并非如此,因为 childLanes 可能与周围环境不一致。
// 这就是我们继续循环的原因。
}
if (node === propagationRoot) {
break;
}
node = node.return;
}
if (__DEV__) {
if (node !== propagationRoot) {
console.error(
'Expected to find the propagation root when scheduling context work. ' +
'This error is likely caused by a bug in React. Please file an issue.',
);
}
}
}

变量

1.当前的指针

// 渲染指针
const valueCursor: StackCursor<mixed> = createCursor(null);

// 渲染器指针 (测试)
let rendererCursorDEV: StackCursor<Object | null>;
if (__DEV__) {
rendererCursorDEV = createCursor(null);
}

// 渲染器指针 2 (测试)
let renderer2CursorDEV: StackCursor<Object | null>;
if (__DEV__) {
renderer2CursorDEV = createCursor(null);
}

2.渲染器符号

let rendererSigil;
if (__DEV__) {
// Use this to detect multiple renderers using the same context
// 使用此方法检测多个渲染器是否使用相同的上下文
rendererSigil = {};
}

3.当前渲染的 Fiber

let currentlyRenderingFiber: Fiber | null = null;

4.上一次上下文依赖

let lastContextDependency: ContextDependency<mixed> | null = null;

5. 在开发环境中禁止读取的上下文

let isDisallowedContextReadInDEV: boolean = false;