React Context
🌱 This post is in the growth phase. It may still be useful as it grows up.
Contents
- A “Shit” Example
- Create, Consume, and Provide Context
- Provide
value
- Authoring and Modules
- Cascading Context
- Data Distribution, Not State Management
- A Mental Model for Context
useContext
Hookstatic contextType
Hook
A “Shit” Example
This is a shit example of Context. Shit because it uses “shit” as an illustration and because it’s simplistic.
We’ll get to the why after we cover the how.
”Shit” is a fine word
“Shit” is fine word in my house.
But my mom hates it.
I tell my kids: “when your at grandma’s house, use a different word.”
Let’s implement this scenario using React Context.
Prefer video?
Create, Consume, and Provide Context
Context is a 3-part system: create, use, provide.
Create
Context must first be defined.
Create context using React.createContext
.
Create (with default value)
React.createContext takes take an optional. Define it using a sensible fallback
Prefer video?
Use
Context is accessed with the React.useContext
hook.
Consumer
Provided functions get the Context’s value
as their first argument.
In this example, value
is the default value used to create NameContext
.
So, how do we provide Context? I’m always glad you ask…
Prefer video? Watch along at learnreact.com.
Provide
Provider
is a component that takes a value
prop and makes it available to every component in the component tree below it.
Providers
work where components are deeply nested.
Prop Drills not required for assembly.
Prefer video? Watch along at learnreact.com.
Provide value
A Context’s value
can take any shape.
Here are examples of valid Contexts values, using a default value
:
value
can be complex structures like React Elements, class components, and function components.
value
is required on Context Providers
Where a Context Provider
is used, the value
prop is required.
What about the default value
given to createContext
?
The default value given to createContext
is used for Consumer
components without a Provider
.
Where Provider
s wrap their Consumer
s, all bets are off.
You must explicitly provide a value
.
Prefer video? Watch along at learnreact.com.
Authoring and Modules
A Context’s Consumer
and Provider
components can be accessed in 2 ways.
The Examples above use JSX’ property access syntax. This is the style used in official documentation.
Above, you access the Provider
and Consumer
components through the Context object.
You may prefer to use object destructuring to assign Provider
and Consumer
components to local variables.
Take care where multiple contexts are used.
Cascading Context
Context cascades.
Consumers use the value from the nearest Context.Provider
.
Where none is present, the createContext
default value is used.
Data Distribution, Not State Management
Context makes it possible to distribute data to every component in a component tree.
It’s used to distribute data, not manage state. That said, it provides the mechanism needed to state and updater functions managed by state containers.
Here’s an example of a stateful container that uses Context to distribute local state
and an update
function.
Modularazing Context
In the “real world”, you’ll likely expose Contexts via ES Modules.
Consumer
s can be imported to compose context-aware components.
Provider
s can be imported to contain and supply values to context-aware components.
A Mental Model for Context
Props are like wires. Props are used to “connect” data between components. Like wires, the components have to be “touching”. Meaning that component thats hold data have to render components that need it.
Context is like a wireless — like infrared.
Context is used to send a “signal”.
Like wireless, components have to be “in range” — children of a Context.Provider
— to recieve the signal.
Components can observe that signal with a Context.Consumer
.
useContext
Hook
As of v16.8 React provides a Hooks API for consuming context.
The main difference between the Context.Consumer
component and the useContext
Hook is this:
The useContext
Hook requires a component boundary;
Context.Consumer
can be used inline.
Here’s a re-implementation of A “Shit” Example using hooks:
static contextType
Hook
Class components can consume one Context directly using static contextType
.
This differs from Context.Consumer
in that it happens in the component definition and it can only consume one Context.
Access to context is done thru the component instance.
Here’s a re-implementation of A “Shit” Example using static contextType
:
© 2018 Michael Chan Some Rights Reserved
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.