Use Context and Custom Hooks to share user state across your React App

Fatma Ali
4 min readMar 20, 2021

The hooks and context API changed the way we build React apps forever. The new API would help in building components in a more functional and reusable way. In this blog, we are going to see how we could use hooks and context to share the user object across the app.

Note: Before we start

As the original docs say:

Context is primarily used when some data needs to be accessible by many components at different nesting levels. If you only want to avoid passing some props through many levels, component composition is often a simpler solution than context.

Additionally, I’m going to assume that you have an already running React App, so we’re going to work with some high-level methods to shorten the blog.

Why use Context for this use-case, and are there alternatives?

In some apps, we find the need to have access to the user object in many deeply nested components. Previously, to achieve sharing an object across many parts of the app, global state management libraries like redux were used. Even worse, prop drilling was used to pass down the props to child components.

Many opt for the inbuilt Context API for its simplicity, and the fact that it comes with React so you don’t need to install a third-party library.

Defining the context

Let’s consider the example below

We are declaring the context in the UserContext variable, then making it accessible throughout our app with UserContext.Provider . Pretty straightforward right?

However, this solution is limiting because apps are usually more complicated than this. Often we have routing in place, and we’d want some routes protected and some opened.

Extending the implementation

First, let’s move the context into its own file for better readability.

Defining the context

Here, we’ve created a wrapper to handle our user context logic. We’ve also renamed it to AuthContext . The AuthContext now provides the current user, as well as the setter for the current user. Awesome, right?

Okay, let’s define a simple custom hook to consume our context in the child components.

Defining a simple custom hook to consume the context

That’s it! So let’s consume it.

First off, we would have to provide the context in our application root as shown below. You can see that we’re getting our user object from sessionStorage We’re assuming that she logged in earlier and we persisted her details in session storage. This is done to prevent us from losing her user info once she refreshes the page, forcing her to log in again.

There are many ways to do this with pros and cons in each. For now, let’s use this as just an example.

Consuming the context

Assuming you’re using react-router, we could define our routes like so:

We’ve defined different routes for our app, some are protected while some are not. For the protected routes, you could see that we have defined a wrapper component called <ProtectedRoute> . The implementation <ProtectedRoute> is shown below:

Defining routes

So far so good! Lastly, let’s see how we can implement and consume the authentication context within our login component.

How to consume context in the user sign in

Finally, let’s assume that we need to implement the ability to logout within a nested child component inside our app. How would that implementation look like?

sign out implementation

And that’s it! You can extend the context and add more values as you need, but this pretty much enables you to share the current user state across the app. Feel free to drop in questions/suggestions below! Thanks for reading!

--

--

Fatma Ali

Software Engineer, passionate about code, food & art. Bollywood dancer sometimes💃 Find me on GitHub https://github.com/fatmali