Let's see how we can use NextJs 13 with the React Context API.
We will make an example that uses the React Context API to set a theme color on the pages of our app. Given that we are using the context API the color value is easily sent from one page to another.
Check out this video to see the app in action:
Adding the React Context store to a NextJs app
First, we will need to create the React Context store. We will place it in app/context/theme.js
:
// app/context/theme.js
'use client';
import { createContext, useContext, useState } from "react";
const ThemeContext = createContext({})
export const ThemeContextProvider = ({ children }) => {
const [color, setColor] = useState('red');
return (
<ThemeContext.Provider value={{ color, setColor }}>
{children}
</ThemeContext.Provider>
)
};
export const useThemeContext = () => useContext(ThemeContext);
Note the 'use client' directive that marks the context component as a client one. Wrote more about NextJs 13 client components here.
The theme context stores and manipulates only the color
value.
Passing the React Context to the NextJs layouts
The next step is to make available the context built in the previous step. Given that we need access to this context on all the pages the best place would be to use the provider in the main layout page:
import { ThemeContextProvider } from './Context/theme'
export default function RootLayout({ children }) {
return (
<html lang="en">
<head />
<body>
<ThemeContextProvider>
{children}
</ThemeContextProvider>
</body>
</html>
)
}
Note that this works because the `children` property from the layout is later used in the context provider:
// app/context/theme.js
<ThemeContext.Provider value={{ color, setColor }}>
{children}
</ThemeContext.Provider>
Using the React Context within the NextJs 13 pages
Now that the context provider setup is done, the final step will be to read and update the context values.
Our app only has two pages: the main page at `/` and a second page at `/second`. Both of them will have a very similar code:
'use client'
import { useThemeContext } from './Context/theme'
import Link from 'next/link'
export default function Main() {
const { color, setColor} = useThemeContext();
return (<>
<h1 style={{'color': color}}>Main page </h1>
<p>Current color: {color}</p>
<button onClick={()=> setColor('blue')}>Set color to blue</button>
<p><Link href="second">Goto second page</Link></p>
</>)
}
Both pages are reading the context value and updating it.
Given that also these pages are using hooks we will need to mark them as client components.
And that's it! A small example of the React Context API used in NextJs 13.
The full code of the example is here.
📖 50 Javascript, React and NextJs Projects
Learn by doing with this FREE ebook! Not sure what to build? Dive in with 50 projects with project briefs and wireframes! Choose from 8 project categories and get started right away.
📖 50 Javascript, React and NextJs Projects
Learn by doing with this FREE ebook! Not sure what to build? Dive in with 50 projects with project briefs and wireframes! Choose from 8 project categories and get started right away.
Thanks for writing this man. Totally fixed my problem
Hi Ztokyo! Glad to know it was helpful! Funny fact, you are the first to comment EVER on this blog as I activated the comments yesterday for the first time.
Thanks for that 🙂
Doesn’t this defeat the purpose of having React Server Components?
Hey Alex T! Yes, it can but so far this was the only way I’ve found how to do it.
This is AWESOME!!!!
Hi Ziaul! Thanks a lot man. Really glad you liked it !
I added this to my project and when I navigate away to another page then return, the state is lost. I don’t know what I am doing wrong.
hi Nick! Not sure what could be wrong. Can you please point me to some code?
Excellent, straight to the point. Thanks!
Thanks 🙂