days
-6
-4
hours
-1
-6
minutes
-2
-3
seconds
-3
-2
search
Solving state management for React

Simplify state management for React applications with the new Context tool

Lokesh Gupta
Context
© Shutterstock / Vitya_M

Get ready for a React revolution! Thanks to the new Context tool, React developers can automatically pass data through the component tree. In this article, Lokesh Gupta goes over the fundamentals of Context and explains how developers can implement it in their React applications.

Rumors are flying around the React ecosystem! Could Context replace redux? Does it make prop drilling extinct? Even if Context doesn’t exactly mean world peace, the React team has introduced a fantastic tool to simplify one of the most difficult problems that 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.

What is Context?

Imagine React is a toolbox. In React 15, developers could only use prop drilling to manage their application’s state.

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 also introduced complexity, increased the bundle size, and required learning another library in addition to React.

Like all abstractions, these tools came burdened with trade offs that felt worth it for large applications, but seemed like overkill for small and mid-sized applications.

When should I use 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.

Don’t hesitate to keep on using 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. Plus, it’s a more complicated abstraction than prop drilling.

SEE ALSO: React framework Next.js 8 goes serverless for mobile web apps

How do I use Context?

Now that 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 apps. 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 also created a Code Sandbox you can explore! I’ll also walk you through my example step-by-step in the sections below.

Prop drilling

I’ve built an application that stores a family’s last name in a component. The component than displays the last name.

We use prop drilling to pass the lastName prop from the component, through the component, to the component, which displays the last name.

const App = () => <Grandmother />
      
class Grandmother extends React.Component {
  state = {
    lastName: "Sanchez"
  } 
  render() {
    return <Mother lastName={this.state.lastName} />
  }
}
const Mother = ({ lastName }) => {
  return <Child lastName={lastName} />
}
const Child = ({ lastName }) => {
  return 

{lastName}

}

SEE ALSO: Meet Kalium, a reactive Java framework for microservices

Context

We can refactor this example to use Context instead. Using Context means we don’t need to pass the lastName through the 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.

import React from "react";
const FamilyContext = React.createContext({});
export const FamilyProvider = FamilyContext.Provider;
export const FamilyConsumer = FamilyContext.Consumer; 

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:

import React from "react";
import { FamilyProvider, FamilyConsumer } from "./FamilyContext";
export class Grandmother extends React.Component {
  state = {
    lastName: "Sanchez"
  };
  render() {
    return (
      // We wrap all of the components that need access
      // to the lastName property in FamilyProvider.
      <FamilyProvider value={this.state.lastName}>
        <Mother />
      </FamilyProvider>
    );
  }
}
const Mother = () => {
  return <Child />;
};
const Child = () => {
  // We wrap the component that actaully needs access to
  // the lastName property in FamilyConsumer
  return <FamilyConsumer>{context => 

{context}

}</FamilyConsumer>;
}; 

SEE ALSO: Meet Verified React: The future of automated reasoning?

Now, we have wrapped the component with because it contains 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 component so that it has access to the context.

Let’s dig a bit deeper into <p>. 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!

What’s a render prop?

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.

const Child = () => {
  // Family Consumer uses the
  // Function as a Child pattern
  return <FamilyConsumer>
    // context is the object with lastName
    // on it. It gets passed as an argument
    {context => 

{context}

}
  </FamilyConsumer>;
};

</FamilyConsumer>; uses a render prop to expose the context object to its children (in this case a <p> tag but it could be anything).

SEE ALSO: React v16.8 arrives with Hooks available in a stable release

In conclusion

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.

Author

Lokesh Gupta

With over two years as a Full Stack Developer and a history in the IT industry, Lokesh Gupta enjoys solving complex problems under budget and within deadlines while using his PHP, MySQL, Python, Codeigniter, Yii2, Laravel, AngularJS, ReactJS, and NodeJS skills. With his thorough knowledge of UML & visual modeling, application architecture design & business process modeling, Lokesh has successfully delivered various projects based on different technologies across the globe.


Leave a Reply

Be the First to Comment!

avatar
400
  Subscribe  
Notify of