You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
functionreadContextForConsumer<T>(
consumer: Fiber | null,
context: ReactContext<T>
): T {// 拿到context值constvalue=isPrimaryRenderer
? context._currentValue
: context._currentValue2;// lastFullyObservedContext只等于nullif(lastFullyObservedContext===context){// Nothing to do. We already observe everything in this context.// 没什么可做的}else{constcontextItem={context: ((context: any): ReactContext<mixed>),memoizedValue: value,next: null,};if(lastContextDependency===null){// consumer就是当前组件的fiberif(consumer===null){// 只有在 React 渲染时才能读取上下文。// 在类中,您可以在 render 方法或 getDerivedStateFromProps 中读取它。// 在函数组件中,可以直接在函数体中读取,但不能在钩子(如 useReducer() 或 useMemo())中读取。thrownewError("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;// 设置fiber.dependenciesconsumer.dependencies={lanes: NoLanes,firstContext: contextItem,};}else{// 链接下一个contextlastContextDependency=lastContextDependency.next=contextItem;}}// 返回valuereturnvalue;}
什么时候会更新 context
从上面的代码可以看出,context 的 value 保存在 context._currentValue,那什么时候会更新这个值呢?
是不是通过<Context.Provider value={value} />中 value 来更新 context 呢,来看下Provider
useContext
createContext
createContext
生成一个context
对象,并且有两个属性,一个是 ·,一个是Consumer。``Provider
类型是REACT_CONTEXT_TYPE
Consumer
类型是REACT_CONSUMER_TYPE
,在生成对应 fiber 的时候会用到readContextForConsumer
什么时候会更新 context
从上面的代码可以看出,
contex
t 的value
保存在context._currentValue
,那什么时候会更新这个值呢?是不是通过
<Context.Provider value={value} />
中value
来更新context
呢,来看下Provider
Provider
看下
beginWork
中对于REACT_CONTEXT_TYPE
这个类型的处理updateContextProvider
pushProvider
propagateContextChange
总结
看完上述代码可能会有几个问题:
context
更改导致重新渲染的整个流程是什么state
更改调度一个更新beginWork
中,走到updateContextProvider
函数中props
中的value
更新context._currentValue
value
是否相同children
是否有更改,如果没有则命中bailout
提前结束propagateContextChange
=>propagateContextChange_eager
更新子节点的lanes
dependencies.lanes
有什么用?context
是以什么形式存在的?React.createContext
创建一个context
对象useContext
中创建contextItem
通过next
链接下一个context
,保存在fiber.dependencies.firstContext
中contextItem
是通过lastContextDependency
穿起来的,如何保证这个变量的生命周期只在当前fiber
节点内?lastContextDependency
变量会在prepareToReadContext
函数内重置<Context>
等同于<Context.Provider>
,具体看issueThe text was updated successfully, but these errors were encountered: