Skip to content

实现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 />
  1. 嵌套的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 beginWorkcompleteWork 一一对应 prevContextValue 的值跟随栈而变化

Context的消费

需要考虑: 从context 取值 两个需要注意的点

  1. React 性能优化造成的影响 上述例子中,如果shouldComponentUpdatefalse ,如何感知子孙组件中有Context
Consumer ?

Context ProviderbeginWork 开始向下遍历寻找Context Consumer : 但是在我们的实现中,还没实现bailout ,所以实现context 不需要考虑这种情况。 2. useContext 没有其他hook 的限制

用心学习,用代码说话 💻