path:packages/react-reconciler/src/ReactFiberNewContext.js
readContext
export function readContext<T>(
context: ReactContext<T>,
observedBits: void | number | boolean,
): T {
if (__DEV__) {
// do something
}
if (lastContextWithAllBitsObserved === context) {
// Nothing to do. We already observe everything in this context.
} else if (observedBits === false || observedBits === 0) {
// Do not observe any updates.
} else {
let resolvedObservedBits;
// Avoid deopting on observable arguments or heterogeneous types.
// 避免对可观察的参数或异构类型进行deopting。
if (
typeof observedBits !== 'number' ||
observedBits === MAX_SIGNED_31_BIT_INT
) {
// 观察所有更新
lastContextWithAllBitsObserved = ((context: any): ReactContext<mixed>);
resolvedObservedBits = MAX_SIGNED_31_BIT_INT;
} else {
resolvedObservedBits = observedBits;
}
let contextItem = {
context: ((context: any): ReactContext<mixed>),
observedBits: resolvedObservedBits,
next: null,
};
if (lastContextDependency === null) {
invariant(
currentlyRenderingFiber !== null,
'Context can only be read while React is rendering. ' +
'In classes, you can read it in the render method or getDerivedStateFromProps. ' +
'In function components, you can read it directly in the function body, but not ' +
'inside Hooks like useReducer() or useMemo().',
);
// 如果这是该组件的第一个依赖项。创建一个新列表。
lastContextDependency = contextItem;
currentlyRenderingFiber.contextDependencies = {
first: contextItem,
expirationTime: NoWork,
};
} else {
// 追加一个新的 context 项。
lastContextDependency = lastContextDependency.next = contextItem;
}
}
return isPrimaryRenderer ? context._currentValue : context._currentValue2;
}
readContext 函数接受两个参数:
context:一个ReactContext对象observedBits
readContext 会将传入的参数 context 经过封装后添加到当前组件的 fiber 的 contextDependencies 链表的末尾。
最后,readContext 会返回当前 context 中存储的值。