preface

The React source reference version is 17.0.3. This is the React source series second, it is recommended that first look at the source of the students from the first to see, so more coherent, there are source series links below.

The warm-up to prepare

UseContext allows us to pass variables directly across the component hierarchy, avoiding the need to manually pass props at each level. It is shared and used in conjunction with createContext.

createContext

CreateContext Creates a context for providers and consumers. Providers mainly expose the content of the context. Consumers can use the content exposed by the Provider of the corresponding context.

Example code:

export const Context = createContext(null)

<Context.Provider value='initialValue'>
  <Context.Consumer>
    {(v) => {
      return <h2>{v}</h2>
    }}
  </Context.Consumer>
</Context.Provider>
Copy the code

Provider

< context. Provider> During rendering, beginWork phase, will be executed

pushProvider(workInProgress, newValue);
Copy the code

It stores the value field of the Provider’s prop in context._currentValue.

Consumer

< context. Consumer> At render time, beginWork phase, will execute

prepareToReadContext(workInProgress, renderLanes);
var newValue = readContext(context, newProps.unstable_observedBits);
Copy the code

You can get the value on the Provider’s prop by using the above code.

Note that the Consumer tag must contain a function, and an error will be reported if it is not a function. The Consumer passes the value as an argument to the function and uses it. This is the same as the v obtained in the above example code.

useContext

UseContext requires that the Context created by createContext be invoked as a parameter.

It is worth mentioning that the hook mentioned above has two different sets of functions to execute during initialization and update. But there is only one in useContext, which means that useContext executes a set of code during initialization and update.

Initialize mount & update update

UseContext calls the readContext function when mounting:

Function readContext(context, observedBits) {var contextItem = {context: context, observedBits: ResolvedObservedBits, next: null}; lastContextDependency = contextItem; currentlyRenderingFiber.dependencies = { lanes: NoLanes, firstContext: contextItem, responders: null }; } else { // Append a new context item. lastContextDependency = lastContextDependency.next = contextItem; } return context._currentValue ; }Copy the code

ReadContext creates a contextItem and records it in a linked list on the corresponding fiber.dependencies file. Then return the value on the Provider’s prop.

conclusion

The principle of useContext is similar to the observer mode. The Provider is the observed, and the Consumer and useContext are the observers. When a value on the Provider changes, the observer can see it and synchronize the information to the component.

The main usage scenario is the passing of multi-level component values. If there are many values, you can consider using useReducer with it.

After reading this article, we can understand the following questions:

  1. useContextHow does it work?

Article series arrangement:

  1. React Fiber;
  2. React source series 2: React rendering mechanism;
  3. React source series 3: hooks useState, useReducer;
  4. React code series 4: hooks useEffect;
  5. React code Series 5: Hooks useCallback, useMemo;
  6. React source Series 6: Hooks useContext;
  7. React source series 7: React synthesis events;
  8. React source series eight: React diff algorithm;
  9. React source series 9: React update mechanism;
  10. React source series 10: Concurrent Mode;

Reference:

React official documents;

Making;