Rumors are flying! Could Context replace redux? Does it make prop drilling extinct? Even if Context !== world peace, the React team has introduced a fantastic tool to simplify one of the most difficult problems frontend developers deal with daily: state management.
Over the past six months, there has been plenty of hype about the new Context. At the end of this post, you’ll know what it is, whether and when you should use it, and how to implement it in your applications.
Redux? Is that you?
Imagine React as a toolbox. In React 15, developers could only use prop drilling to manage their application’s state. (If you don’t know about prop drilling yet, go read this post. I’ll wait).
Developers started reaching for other toolboxes, like redux and MobX to help with more complicated state management. They offered alternative solutions to managing state, but they introduced complexity, increased the bundle size, and required learning another library in addition to React.
Like all abstractions, these tools came burdened with tradeoffs that felt worth it for large applications, but seemed like overkill for small and mid-sized applications.
‘Sup. It’s me, Context.
I would recommend reaching for Context when you find yourself passing props down through three or more levels in your component tree. You might notice that you have renamed your props, making it challenging to determine the data’s origin. You might consider implementing context if a bunch of your components know about irrelevant data.
Rule of thumb: if you start to feel irritated by how long it takes to determine where data is coming from, introduce Context.
Do not hesitate to still use the other tools you have available, like prop drilling and redux. While Context can make it easier to pass props around in certain scenarios, it doesn’t give you access to some of the benefits redux offers, and it’s a more complicated abstraction than prop drilling.
(If you’re interested in more of the benefits redux offers, check out Dan Abramov’s You Might Not Need Redux).
Now you know what Context is, and when to use it! I’m sure you’re jumping at the bit to discover how to implement it in your applications. I created an example to show how you might replace prop drilling with Context as your application grows.
If you’re into interactivity, I’ve created a
you can explore! I’ll also walk you through my example step-by-step.I’ve built an application that stores a family’s last name in a <Grandmother />
component. The <Child />
component than displays the last name.
The gorgeous result of this application looks like this:
#stunning
We use prop drilling to pass the lastName
prop from the <Grandmother />
component, through the <Mother />
component, to the <Child />
component, which displays the last name.
We can refactor this example to use Context instead. Using Context means we don’t need to pass the lastName
through the <Mother />
component. We circumvent components that don’t need to know the lastName
property, and share that state only with components that need to know it.
First, we will need to create our Context.
We use createContext()
and pass it an empty object as the default value:
const FamilyContext = React.createContext({});
We then create a Provider
and a Consumer
component and export them so they are available for consumption by other components in your application.
export const FamilyProvider = FamilyContext.Provider;export const FamilyConsumer = FamilyContext.Consumer;
Here’s a full example of how we will use the Provider and Consumer:
Now, we have wrapped the <Mother />
component with <FamilyProvider />
because it contains <Child />
which is the component that needs access to the lastName
prop.
<FamilyProvider value={this.state.lastName}><Mother /></FamilyProvider>
Notice that the Provider has a value prop. Pass in whatever state you’d like to share. In our case, we want to share the lastName
so we pass in this.state.lastName
.
To actually have access to the lastName
, we have also wrapped the <p>
tag on line 27 in the <FamilyConsumer />
component so that it has access to the context
.
Let’s dig a bit deeper into <FamilyConsumer />
!
At first, it might look a bit confusing if you aren’t familiar with the render prop pattern, but with a bit of explanation I think you might find that it’s a fairly straightforward implementation. You don’t need to know how to build a render prop to use Context, but it’s a really powerful abstraction!
A render prop is a way of writing components in React so that they are reusable, and can take n number of children of any type. Render props appear in a couple of different disguises. Context implements a Function as a Child Pattern, which is just a render prop called children
. If you want to learn more about render props, you can read When Not to Use Render Props by Kent C. Dodds or go straight to React’s documentation on the subject.
<FamilyConsumer />
uses a render prop to expose the context
object to its children (in this case a <p />
tag but it could be anything).
Ultimately, Context is a great tool to add to your React toolbox. Use it when you find prop drilling has become too complex, but your application isn’t large enough to warrant a third-party solution like MobX or redux.
🌟 If you liked this post, make sure to follow me on medium, follow me on twitter, and support me on Patreon**!**🌟