react context 源码解读

源码地址

注: 这里,为了读起来思路更清晰一些,我们将__DEV__的代码去掉。

import {REACT_PROVIDER_TYPE, REACT_CONTEXT_TYPE} from 'shared/ReactSymbols';

import type {ReactContext} from 'shared/ReactTypes';

export function createContext<T>(
  defaultValue: T,
  calculateChangedBits: ?(a: T, b: T) => number,
): ReactContext<T> {
  if (calculateChangedBits === undefined) {
    calculateChangedBits = null;
  }

  const context: 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,
    _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 circular
    Provider: (null: any),
    Consumer: (null: any),
  };

  context.Provider = {
    $$typeof: REACT_PROVIDER_TYPE,
    _context: context,
  };

   context.Consumer = context;

  return context;
}

全局创建的context实例,对外提供Provider和Consumer两个属性,Provider的_context属性值又指向context实例本身,即:当改变Provider组件value的值,会作用到Provider内部的_context属性,进而更新context的_currentValue. 而

context.Consumer = context

所以会触发consumer的更新。

 

参考:https://xie.infoq.cn/article/d56577c78e76508722e37025f

posted @ 2021-02-03 10:52  cecelia  阅读(78)  评论(0编辑  收藏  举报