DEV Community

Cover image for React Context API: A Comprehensive Guide
Kada Guetouache
Kada Guetouache

Posted on • Updated on

React Context API: A Comprehensive Guide

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')
Enter fullscreen mode Exit fullscreen mode

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: () => {}
})
Enter fullscreen mode Exit fullscreen mode

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 in main.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 it theme, 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>
  )
}
Enter fullscreen mode Exit fullscreen mode

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>,
)
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

and in other components just import this custom hook

import {useTheme} from 'themeContext'

const App = () => {
  const {theme, setTheme} = useTheme()

  return(...)
}
Enter fullscreen mode Exit fullscreen mode

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.

Thank you for reading.

Top comments (5)

Collapse
 
gotplitz profile image
Norman C. Pleitez

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?

Collapse
 
kada profile image
Kada Guetouache

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.

Collapse
 
gotplitz profile image
Norman C. Pleitez

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.

Collapse
 
terry_gilligan_e4bf4680b8 profile image
Terry Gilligan

Thank you for taking the time to post it's very useful. Have a great day.

Collapse
 
kada profile image
Kada Guetouache

Thank you for taking time and reading this post. I'm glad you found it helpful