Introduction
React context API is a way to share state across multiple components without the need to pass data through each level of component tree. React context API essentially creates a data layer that allows components to subscribe and access data without been direct child of the component that's providing the data.
Why use React Context API
The context API creates a global state that is accessible through the whole application which results in simple and structured data flow through components and makes the hole code cleaner and organized.
Understanding the basics
Through this whole post we will be creating a global theme context just for the sake of simplicity.
Creating a context
we will create a file called themeContext.jsx
and passed the following logic in it.
creating a context can be done in simple steps which is importing and calling createContext
with default options
import {createContext} from 'react'
export const ThemeContext = createContext('light')
we will also need to change the theme mode so we are going to add a function to default options.
import {createContext} from 'react'
export const ThemeContext = createContext({
theme: 'light',
setTheme: () => {}
})
Creating a Provider
For our context API be accessible through all components, we will need to create a provider and then wrap our application or parts of it with the context provider. In this case we will wrap the whole application.
most of context API logic will also be inside the provider for our case we will only need a useState
to change the theme mode but more expensive logic can be placed in context provider.
Steps:
- import
useState
cause we will need it. - create a functionnal components and export it for better naming convention we will call it
ThemeProvider
. - the
ThemeProvider
must accept children because we are gonna wrapped it around our application inmain.jsx
file (I'm using React with Vite). - Create a Theme state in our case the logic is only needed. but more complex logic can be used in here.
- return
ThemeContext.Provider
the ThemeContext created in first step, then pass to ittheme, setTheme
to value because we want to access those values in other components.
import {useStaet} from 'react'
export const ThemeProvider = ({children}) => {
const [theme, setTheme] = useState('light')
return (
<ThemeContext.Provider value={{theme, setTheme}}>
{children}
</ThemeContext.Provider>
)
}
Next step is to go starting point of your application, this works for our case put you choose other location depending of your use case.
import the ThemeProvider
and wrap <App />
with our context provider. This step make sure that the theme, setTheme
state is accessible through the whole application.
createRoot(document.getElementById('root')!).render(
<StrictMode>
<ThemeProvider>
<App />
</ThemeProvider>
</StrictMode>,
)
Consuming the provider
Now in any other component we will need to call useContext
from react and ThemeContext
from themeContext.jsx
file.
then destruct the theme,setTheme
values and use them in you component.
import {useContext} from 'react'
import {ThemeContext} from './themeContext'
const App = () => {
const {theme, setTheme} = useContext(ThemeContext)
// some logic to change background color here
return(
<div>
<button onClick={() => setTheme("light")}>Light</button>
<button onClick={() => setTheme("dark")}>Dark</button>
</div>
)
}
export default App;
Enhancing Context API with custom react hook
PS: I have already created a post about getting started with custom hooks in react if you have any issues please click here
we can avoid calling useContext
from react and ThemeContext
by defining a custom react hook.
In themeContext.jsx
file create a custom hooks called useTheme
const useTheme = () => {
const context = useContext(ThemeContext)
if (!context) throw New Error('something went wrong!')
return context
}
and in other components just import this custom hook
import {useTheme} from 'themeContext'
const App = () => {
const {theme, setTheme} = useTheme()
return(...)
}
Conclusion
In this guide we have dived into understanding the context API, and demonstrate it's efficacy in streaming data across the components of your application. We have created a context and it's provider and wrapped our app with context provider and learn how to consume the provider and even enhance the code by utilizing custom hooks.
Top comments (5)
So I have a Next JS app, I am using a component that is connected to a context and I am calling it from the server side page, in anothe section of that page I have another component that uses the client side and uptates the context, but the other component doesn’t update until I refresh the page. Is there a work around for that without changing the whole page to client side?
How you are accessing context in server side? bcs you shouldn't be able to do that.
if you have client component that passes context to server component, you should have no issue.
Yeah, the components both have 'use client' at the top, but they are both called in differe parts in a page route that is server side.
taqueriamariabonitava.com/about-ta... This is the site. The top bar shows Dine in - Curbsie… but when I scroll down I should be able to set my perefered location and in the top bar will show the location and the address. Those two components are client side, but the page and the rest of content it is not. For now the page refres automatically after click the preferred location.
Thank you for taking the time to post it's very useful. Have a great day.
Thank you for taking time and reading this post. I'm glad you found it helpful