A Quick Guide to useContext() in React

A beginner’s guide to taking your React skills and projects to the next level

Andrew Stahl
5 min readFeb 13, 2023
Title image; A Quick Guide to useContext() in React

Agenda

  • Why Do We Need useContext()?
  • Project Overview
  • Pitfalls
  • Resources

**Important — this guide assumes you have basic to intermediate skills in working with React. Please brush up on that before continuing**

Why Do We Need useContext()?

One of the best parts of React is the ability to pass values throughout your application so that the data is in sync. A frequent example of this setup is to pass current user information throughout the application. That way, the application can greet them by their username, only show them settings depending on their permissions, etc.

This code shows what this can look like in action —

Nice! Now every component has access to this user data. The best practice is to house your state props at the nearest parent component of the components that need to access the data, so we have things stored in the app.js file.

Although this makes React applications incredibly dynamic, it can quickly become cumbersome to keep passing in these props throughout your components. Remember, you must also pass this user prop into all subsequent child components. If each of those components has another five child components, that’s a lot of real estate. And what about other props you want to pass through these child components? Remember this rule of thumb with your props: “Three props is fine. Five props is a code smell. More than seven props is a disaster”.

Luckily for us, the developers at React came out with some great solutions for this problem. You can utilize something like Redux for universal state management, but that is also a complex endeavor if you don’t truly need it. Instead, we will review the useContext hook from React.

According to React Docs, “useContext is a React Hook that lets you read and subscribe to context from your component.” Let’s check out a real-world project to see it in action.

Project Overview

We started working on a basic project management application in the above code. There should be pages for projects, communication, and profile. We want to display a login page if the user has not logged in.

The first thing we need to do is create a context for the user. We will call this UserContext.

You can create a default value for your context within the createContext function like this: React.createContext(defaultValue). We will leave that default value off for now.

Now that we have created our context, we need to wrap any child components that need access to those state variables in a Provider function. This functions the same way as passing the variables in as props, but it’ll be much cleaner. This is how it would look:

Notice that we’re passing a single value in the Provider — our “user” stateful variable. The Provider only allows for one prop. If you are trying to pass in multiple separate props through this Provider (i.e. other stateful elements that you need to pass throughout your application), you would need to create another context. It is also expensive to run multiple context providers, but we will keep things simple for this post.

Okay, so now that we have the context and provider setup, let’s create a basic workflow that will conditionally render the login page. I will use another React hook, useRef, to grab the current username and password values as the user clicks submit.

This is a very bare-bones component but it’ll do the job! This will produce a form that will provide boxes for the user to enter their username and password. Once they click on the “Submit” button, it will trigger the onSubmit function, which will then pass the current username and password values into the onLogin prop function. I also added a “permissions” key that the user does not touch. This might be useful if you give people free trial access or admin permissions.

Let’s look at how everything is functioning on the main App component so far —

Here’s a recap of what we added:

  1. Login component will render if there is no user data
  2. The user data (submitted through the Login form) sends to the App parent component through the onLoginfunction.
  3. The user value is set after the data is routed from the onLogin function to the handleLogin function.

As soon as step #3 completes, it will re-render all components that use the “user” state variable. Luckily for us, that includes the UserContext.Provider function.

This is what the completed App looks like when including all other child components—

Now we’re cooking! The last thing we’ll look at is how to pull in the value of “user” through our child components. After all, this was the main reason we started on this path.

Let’s use the framework for the “Projects” component as an example. We will leverage the useContext hook to pull that value into the component. It’ll look something like this —

Simple as that! Instead of passing values as props through the child components, the UserContext.Provider function will carry the value of whatever is passed into it to the rest of the child components that it is wrapped around. This might not be as useful if you only have a few child components, but if every child component has another child component (i.e. the projects component has projectList, projectForm, projectElement, … components), the value of useContext goes up significantly.

Pitfalls

While useContext is a great way to get around common issues with passing stateful variables through an application, it does have its downsides. According to ReactDocs, “A component calling useContext will always re-render when the context value changes.” That could mean most of your application re-renders if many components pull the context value. It is an expensive process, so you should only use useState, useContext, Redux, and any other React state management processes when needed. Unnecessary use of these hooks can lead to a painfully slow application.

Wrapping Up

You now have what it takes to implement useContext into your application. This hook should help you unlock the potential of your current projects or significantly clean up your previous projects. Try building out the rest of the application mentioned above for some practice.

Until next time, happy coding!

--

--

Andrew Stahl

Passionate Software Developer, Adventurous Explorer, and Avid Movie Quoter