Reactician

Sharing state between Next.js page navigations using React Contexts

Versions used:
  • react@17.0.1

While developing Next.js applications, a common requirement is to keep state alive between page navigations. You might want to keep global state to keep track of a user's preferences, an authentication token, or exposing side-effects as state, think offline mode.

Let's start by implementing a simple example, starting with tracking state on the Next.js page component, then migrating the state to a custom and finally exposing a global React Context.

Keeping track of the state

Imagine we have a page that keeps track of the amount of times the user clicked a button. We use React's hook to declare a new state variable and define a function to increment the click amount and bind it to the button's handler.


Every time you click the button the state will increment by and the page will re-render the view with the new state. However, if you navigate to a different page, the will unmount and throw away its state.

To keep this state in memory between navigations, instead of keeping the state on the page itself, we need to use Next.js' component.

Implementing a custom App component

Next.js uses an component to handle page initializations. This component will be kept alive during the entire application's lifecycle. Overriding this component with a custom implementation, allows us to declare state in the application that will survive page navigations.

Next.js component will keep state alive during client side transitions. If you refresh the page, or link to another page without utilizing Next.js , the will initialize again and the state will be reset.

The Component will receive the current page as and it's properties as . Now we can move the state logic from our into the component and pass the state and handler to every page, not just the .


We'll have to update the , as it's no longer keeping track of states but receiving it through its props, thanks to our component.


Our is now wrapping and rendering all the pages, and Next.js will keep the state alive while mounting and unmounting different pages.

Using a React Context in the custom App

React Contexts are a great feature for sharing global state. If the state is common enough to be used in numerous components, it can be tiresome and error prone to keep passing props multiple levels deep. This is especially true if some of these components only pass the props through to their children, without using or mutating the props.

Contexts allow us to reach these global states without having to worry about passing props. Let's create a new context and provider for our state and our handler.


Now let's update our to use the new component.


Finally, we have to update our , as its no longer receiving the state and handler through it's props, but through the .


By wrapping all the pages with our in our , every page and / or component can now access the exposed state simply by making use of React's hook with the as argument, no matter how deep they are in the tree.

This makes global state neatly structured, while staying easily accessible.

Stephan Lagerwaard
Stephan Lagerwaard
Frontend Engineer at Fiberplane.