DEV Community

Cover image for React Context API: A step-by-step guide
Luqman Shaban
Luqman Shaban

Posted on

React Context API: A step-by-step guide

What is Context?
At its core, Context is a way to share data between components without explicitly drilling through components props. It's a global state management system within your React application.

When to use Context?
You should consider using Context API when you have data or Settings that need to be accessed by multiple components at different levels of your Application's component hierarchy. This may be applied to features like User Authentication, theme preference, language settings etc.

Implementation
To understand clearly how the Context API works, We'll create a simple Theme functionality that is commonly used in many React Applications.
Let's go through the steps of implementing the Context API:

1. Create A context

Create a folder store in your src directory and inside create a file called: ThemeContext.js and import the necessary dependencies:

import React, { createContext, useState } from 'react'
We'll create and export a theme Context that we'll use to share data across our Application.

import React, { createContext, useState } from 'react'

 export const ThemeContext = createContext()
Enter fullscreen mode Exit fullscreen mode

2. Provide the Context

After creating the context, we now have to create a Provider. This is a typical component that wraps the portion of your application where you want to make certain data available to other components. In our case, we'll wrap our Provider in index.js as we want the Theme context to be accessed globally.

To create a Provider, we'll simply create a react component and name it ThemeProvider. We then pass props to the component named children.

  export const ThemeProvider = ({ children }) => {
    }

Enter fullscreen mode Exit fullscreen mode

In the provider, we initialize a state variable and set it to false:

   export const ThemeProvider = ({ children }) => {
        const [isDarkTheme, setIsDarkTheme] = useState(false)
    }

Enter fullscreen mode Exit fullscreen mode

Create a function toggleTheme that will update the state every time its called.

    export const ThemeProvider = ({ children }) => {
        const [isDarkTheme, setIsDarkTheme] = useState(false)

        const toggleTheme = () => setIsDarkTheme(prevTheme => !prevTheme)
    }
Enter fullscreen mode Exit fullscreen mode

3. Consume the Context

To consume the Context, return the provider with the data you want to share with other components and wrap the children props inside.

 export const ThemeProvider = ({ children }) => {
     const [isDarkTheme, setIsDarkTheme] = useState(false)

     const toggleTheme = () => setIsDarkTheme(prevTheme => !prevTheme)

     return (
         <ThemeContext.Provider value={{ isDarkTheme, toggleTheme }}>
             {children}
         </ThemeContext.Provider>
     )
 }
Enter fullscreen mode Exit fullscreen mode

And there you go! You've created a context API in React.

4. Using the Context In the App

To be able to access the data in the Context API, we will have to wrap the portion of our Application with the ThemeProvider for the components to consume the data. So we'll wrap the App component with the Provider.

Open your index.js file, import the ThemeProvider and Wrap the App component with it.
Here's how the index.js file should look:

 import React from 'react';
 import ReactDOM from 'react-dom/client';
 import App from './App';
 import { ThemeProvider } from './store/ThemeContext';

 const root = ReactDOM.createRoot(document.getElementById('root'));
 root.render(
   <React.StrictMode>
     <ThemeProvider>
      <App />
     </ThemeProvider>
   </React.StrictMode>
 );

Enter fullscreen mode Exit fullscreen mode

With this setup, we can access the data throughout the entire application.

5. Use Case 1

In the src directory, create aButton.jsfile and inside import the following dependencies:

 import React, { useContext } from 'react'
 import { ThemeContext } from './store/ThemeContext'
 import './App.css'
Enter fullscreen mode Exit fullscreen mode

Make sure you have App.cssin the same folder for styling the button.

Create a React component called Button and add a button element to it:

 import React, { useContext } from 'react'
    import { ThemeContext } from './store/ThemeContext'
    import './App.css'

    const Button = () => {

      return (
        <button>
          change Theme
        </button>
      )
    }

    export default Button
Enter fullscreen mode Exit fullscreen mode

Import the data from isDarkTheme and toggleTheme from ThemeContext API.

  import React, { useContext } from 'react'
    import { ThemeContext } from './store/ThemeContext'
    import './App.css'

    const Button = () => {
      //Consuming the Data from The context API
      const { isDarkTheme, toggleTheme } = useContext(ThemeContext) 
      return (
        <button>
          change Theme
        </button>
      )
    }

    export default Button
Enter fullscreen mode Exit fullscreen mode

Now that we have accessed the data, we can apply it to our button element. We'll add the onClick event to the button and some styling.

 import React, { useContext } from 'react'
    import { ThemeContext } from './store/ThemeContext'
    import './App.css'

    const Button = () => {
      const { isDarkTheme, toggleTheme } = useContext(ThemeContext)
      return (
        //adding onClick Event and the theme custom styles to the button
        <button onClick={toggleTheme} className={`${isDarkTheme ? 'lightBtn' : 'darkBtn'}`}>
          change Theme
        </button>
      )
    }

    export default Button
Enter fullscreen mode Exit fullscreen mode

6. Use Case 2

Open App.js and add the following dependencies:

 import { useContext } from 'react';
 import './App.css';
 import Button from './Button';
 import { ThemeContext } from './store/ThemeContext';

Enter fullscreen mode Exit fullscreen mode

Inside the App component, import isDarkTheme from the ThemeContext API.

 function App() {
   const { isDarkTheme } = useContext(ThemeContext)
 }

Enter fullscreen mode Exit fullscreen mode

return a div component with the following:

 return (
       //Added the styles based on isDarkTheme Boolean value
       <div className={`App ${isDarkTheme ? 'darkTheme' : 'lightTheme'}`}>
         <h1>Theme Context Api</h1>
         <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorem quam quisquam enim minus, consectetur dignissimos vero beatae possimus reprehenderit sed officia eveniet obcaecati neque architecto ut, magnam odit optio veniam.</p>
         <Button />
       </div>
   );
Enter fullscreen mode Exit fullscreen mode

Here's how the entire file looks:

 import { useContext } from 'react';
 import './App.css';
 import Button from './Button';
 import { ThemeContext } from './store/ThemeContext';

 function App() {
   const { isDarkTheme } = useContext(ThemeContext)

   return (
       <div className={`App ${isDarkTheme ? 'darkTheme' : 'lightTheme'}`}>
         <h1>Theme Context Api</h1>
         <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorem quam quisquam enim minus, consectetur dignissimos vero beatae possimus reprehenderit sed officia eveniet obcaecati neque architecto ut, magnam odit optio veniam.</p>
         <Button />
       </div>
   );
 }

 export default App;
Enter fullscreen mode Exit fullscreen mode

Finally, open App.css and paste the following styles. You can modify them to suit your specific needs.

  * {
      padding: 0;
      margin: 0;
      box-sizing: border-box;
    }
    .App {
      padding: 50px;
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: column;
      gap: 20px;
      height: 100vh;
    }

    .darkTheme {
      background-color: black;
      color: aliceblue;
    }

    .lightTheme {
      background-color: aliceblue;
      color: black;
    }

    button {
      padding: 10px;
      border-radius: 10px;
      border: 1px solid;
      cursor: pointer;
      font-size: 16px;
    }

    .darkBtn {
      background-color: black;
      color: aliceblue;
    }
    .lightBtn {
      background-color: aliceblue;
      color: black;
    }
Enter fullscreen mode Exit fullscreen mode

Run the App

When you run the App in the browser, the theme will change on each button click demonstrating that the data is being shared between the Button component as well as in the App component.

Conclusion
In this article, we explored the concept of using Context API to efficiently share data between components while avoiding prop drilling. To help you understand how the Context API works, we implemented a simple functionality that is commonly used in many React Applications and verified that we were able to share global state across your application.
GitHub Repo

Join our community by subscribing to the newsletter to receive regular updates, fresh insights, and exclusive content.

Let's Connect:
LinkedIn
Twitter
Instagram
Facebook
Website

Top comments (0)