context 怎么实现数据共享的呢?原理是什么?
为什么useContext一下provider提高的就可以直接用呢,因为调用者(也有成为消费者)指向context, 提供者也指向context, 所以才能达到useContext既可以作为提供者,也可以作为调用者
源码
const contextStackCursor = {
current: emptyContextPool,
};
const contextFiberStackCursor = {
current: emptyContextFiberStack,
};
function readContext(context, observedBits) {
const dispatcher = ReactCurrentDispatcher.current;
return dispatcher.readContext(context, observedBits);
}
// 创建一个新的`Context`对象
// `defaultValue`表示在没有匹配到`Provider`组件时的默认值,`calculateChangedBits`表示如果数据发生变化时需要通知哪些`Consumer`。
function createReactContext(defaultValue, calculateChangedBits) {
if (calculateChangedBits === undefined) {
calculateChangedBits = null;
}
// 首先根据传入的参数构建一个包含`Provider`和`Consumer`属性的`context`对象
const context = {
$$typeof: REACT_CONTEXT_TYPE,
_calculateChangedBits: calculateChangedBits,
_currentValue: defaultValue,
_currentValue2: defaultValue,
Provider: null,
Consumer: null,
};
// `Provider`属性对应的是一个`REACT_PROVIDER_TYPE`类型的节点,它包含了一个`_context`属性,该属性指向了当前的`context`对象。
context.Provider = {
$$typeof: REACT_PROVIDER_TYPE,
_context: context,
};
let hasWarnedAboutUsingNestedContextConsumers = false;
let hasWarnedAboutUsingConsumerProvider = false;
// `Consumer`属性对应的是一个`REACT_CONTEXT_TYPE`类型的节点,它包含了一个`_context`属性和一个`_calculateChangedBits`属性,分别指向了当前的`context`对象和计算变化的函数
const Consumer = {
$$typeof: REACT_CONTEXT_TYPE,
_context: context,
_calculateChangedBits: context._calculateChangedBits,
...
};
// !!!
context.Consumer = Consumer;
return context;
}
在使用Context时,我们需要使用Provider组件来提供全局数据,并在需要使用该数据的组件中使用Consumer组件来获取数据
在Provider组件中,我们可以通过value属性设置全局的Context数据,在任何地方都可以通过useContext来读取该数据。
createReactContext函数中的Provider和Consumer属性是Context的核心部分,它们提供了全局的数据传递方式。
_currentValue, _currentValue2有两个值设置是为了解决并发问题
链接:
juejin.cn/post/703093…
juejin.cn/post/684490…