React Context API: A step-by-step guide

React Context API: A step-by-step guide

ยท

6 min read

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()
    
  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 }) => {
     }
    

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

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

    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)
     }
    
  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>
         )
     }
    

    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>
     );
    

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

  5. Use Case 1

    In the src directory, create a Button.js file and inside import the following dependencies:

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

    Make sure you have App.css in 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
    

    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
    

    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
    
  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';
    

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

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

    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>
       );
    

    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;
    

    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;
     }
    
  7. 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

ย