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
exportfunctioncreateContext<T>(defaultValue: T,// context 默认值calculateChangedBits: ?(a: T,b: T)=>number,// 计算新老 context 变化函数): ReactContext<T>{if(calculateChangedBits===undefined){calculateChangedBits=null;}else{if(__DEV__){warningWithoutStack(calculateChangedBits===null||typeofcalculateChangedBits==='function','createContext: Expected the optional second argument to be a '+'function. Instead received: %s',calculateChangedBits,);}}// 声明了一个 context 对象constcontext: ReactContext<T>={$$typeof: REACT_CONTEXT_TYPE,_calculateChangedBits: calculateChangedBits,// As a workaround to support multiple concurrent renderers, we categorize// some renderers as primary and others as secondary. We only expect// there to be two concurrent renderers at most: React Native (primary) and// Fabric (secondary); React DOM (primary) and React ART (secondary).// Secondary renderers store their context values on separate fields._currentValue: defaultValue,// 用来记录 context 最新值,当 Provider value 更新时,同步到 _currentValue 上_currentValue2: defaultValue,// Used to track how many concurrent renderers this context currently// supports within in a single renderer. Such as parallel server rendering._threadCount: 0,// These are circularProvider: (null: any),// context ProviderConsumer: (null: any),// context Consumer};context.Provider={// context.Provider 的 _context 为 context$$typeof: REACT_PROVIDER_TYPE,_context: context,};lethasWarnedAboutUsingNestedContextConsumers=false;lethasWarnedAboutUsingConsumerProvider=false;if(__DEV__){// A separate object, but proxies back to the original context object for// backwards compatibility. It has a different $$typeof, so we can properly// warn for the incorrect usage of Context as a Consumer.const Consumer ={//Consumer 的 _context 也为 context$$typeof: REACT_CONTEXT_TYPE,_context: context,_calculateChangedBits: context._calculateChangedBits,};// $FlowFixMe: Flow complains about not setting a value, which is intentional hereObject.defineProperties(Consumer,{Provider: {get(){if(!hasWarnedAboutUsingConsumerProvider){hasWarnedAboutUsingConsumerProvider=true;warning(false,'Rendering <Context.Consumer.Provider> is not supported and will be removed in '+'a future major release. Did you mean to render <Context.Provider> instead?',);}returncontext.Provider;},set(_Provider){context.Provider=_Provider;},},_currentValue: {get(){returncontext._currentValue;},set(_currentValue){context._currentValue=_currentValue;},},_currentValue2: {get(){returncontext._currentValue2;},set(_currentValue2){context._currentValue2=_currentValue2;},},_threadCount: {get(){returncontext._threadCount;},set(_threadCount){context._threadCount=_threadCount;},},Consumer: {get(){if(!hasWarnedAboutUsingNestedContextConsumers){hasWarnedAboutUsingNestedContextConsumers=true;warning(false,'Rendering <Context.Consumer.Consumer> is not supported and will be removed in '+'a future major release. Did you mean to render <Context.Consumer> instead?',);}returncontext.Consumer;},},});// $FlowFixMe: Flow complains about missing properties because it doesn't understand definePropertycontext.Consumer=Consumer;}else{context.Consumer=context;}// Provider 与 Consumer 均指向 context,也就是说,Provider 与 Consumer 使用同一个变量 _currentValue,当 Consumer 需要渲染时,直接从自身取得 context 最新值 _currentValue 去渲染if(__DEV__){context._currentRenderer=null;context._currentRenderer2=null;}returncontext;}
The text was updated successfully, but these errors were encountered:
sisterAn
changed the title
React 源码解读系列(五)之 createContext
React 源码漂流(五)之 createContext
Jul 24, 2019
sisterAn
changed the title
React 源码漂流(五)之 createContext
React 源码漂流(六)之 createContext
Jul 24, 2019
context
一、初识 context
在典型的 React 应用中, 数据 是通过 props 属性显式的由父及子进行 传递 的,但这种方式,对于复杂情况(例如,跨多级传递,多个组件共享)来说,是极其繁琐的。
第一种解决方式是: 组件的封装与组合,将组件自身传递下去
在项目中,我们在父层获取数据,不同层级的子组件访问时,我们可以使用 将子组件的公共组件封装,将公共组件传递下去 。例如
这种对组件的 控制反转 减少了在应用中要传递的 props 数量,这在很多场景下会使得你的 代码更加干净 ,使你对根组件有更多的把控。但是,这并不适用于每一个场景: 将逻辑提升到组件树的更高层次来处理,会使得这些高层组件变得更复杂,并且会强行将低层组件提到高层实现,这很多时候有违常理。
第二种解决方式是:context
context 提供了一种在 组件之间共享此类值 的方式,使得我们无需每层显式添加 props 或传递组件 ,就能够实现在 组件树中传递数据 。
注意:在大多数情况下,context 一般用来做 中间件 的方式使用,例如 redux。
React.createContext
Context.Provider
Class.contextType
Context.Consumer
二、深入 context
<LocaleProvider.Provider value={{name: 'AnGe'}}>
),因为这样会导致,每次 Provider 的父组件进行重渲染时,都会导致 Consumer 组件中重新渲染,因为value
属性总是被赋值为新的对象(Object.is 新旧值检测)locale-context.js
app.js
SubComponent.js
三、源码解读
The text was updated successfully, but these errors were encountered: