主题
实现useContext
第21课 实现useContext
本节课代码地址(请参考课程获取)
jsx
const ctx = createContext(0);
function App() {
return (
<ctx.Provider value={1}>
<div>
<Middle />
</div>
</ctx.Provider>
);
}
class Middle extends Component {
shouldComponentUpdate() {
returntrue;
}
render() {
return<Child />;
}
}
function Child() {
const val = useContext(ctx);
return <p>{val}</p>;
}context相关实现细节:
Context 的创建(createContext 的返回值) Context 的逻辑
Context 的消费(useContext 实现)Context的创建
jsx
type ReactContext<T> = {
$$typeof: symbol | number;
Provider: ReactProviderType<T> | null;
_currentValue: T;
};Context的逻辑
需要实现两部分内容:
对ContextProvider 类型FiberNode 的支持Context 逻辑的实现
context逻辑的实现
jsx
1. 支持context._currentValue 的变化
const ctx = createContext(0);
<ctx.Provider value={1}>
<Cpn />
</ctx.Provider>
<Cpn />- 嵌套的
context
jsx
<ctx.Provider value={0}>
<Cpn />
<ctx.Provider value={1}>
<Cpn />
<ctx.Provider value={2}>
<Cpn />
</ctx.Provider>
</ctx.Provider>
</ctx.Provider>Q:不同类型context 的嵌套会有问题么?
jsx
<ctxA.Provider value={'a0'}>
<ctxB.Provider value={'b0'}>
<ctxA.Provider value={'a1'}>
<Cpn />
</ctxA.Provider>
<Cpn />
</ctxB.Provider>
</ctxA.Provider>A:不会。因为JSX 结构固定意味着: Provider beginWork 与completeWork 一一对应 prevContextValue 的值跟随栈而变化
Context的消费
需要考虑: 从context 取值 两个需要注意的点
React性能优化造成的影响 上述例子中,如果shouldComponentUpdate为false,如何感知子孙组件中有Context
Consumer ?从Context Provider 的beginWork 开始向下遍历寻找Context Consumer : 但是在我们的实现中,还没实现bailout ,所以实现context 不需要考虑这种情况。 2. useContext 没有其他hook 的限制