DEV Community

Lucy Bullen
Lucy Bullen

Posted on

React Context - an Implementation Quick Guide

Implementing the React Context API is one way to implement global state in an application.

Global state is useful when there are child components that need access to the same piece of state nested in disjointed areas of the component tree. Examples of this include: the toggling of a dark mode layout and accessing user information for personalized application formatting.

The local state management methodology calls for this to be solved using prop drilling - defining state at a shared higher level component and passing the variable down to child components, and child components' child components, using props. With a complex component tree, it can be clunky to pass the state variable as props and inefficient to re-render the entire shared higher level component each time a child component updates state. Enter React Context API for global state management. It allows children components to have access to state variables and state variables' relevant functions without explicitly passing them through the component tree by making them 'global.'

Other global statement management solutions are out of the scope of this article, but learn more about other popular options here: State Management Battle in React 2022: Hooks, Redux, and Recoil

The syntax required for the React Context API global state management consists of:

  • the createContext object
  • the context provider component
  • the useContext hook

the createContext object

The createContext object initializes the use of context in a React application.

To create the createContext object, import React and set a constant equal to React.createContext().

import React from 'react';

const GlobalContext = React.createContext();
Enter fullscreen mode Exit fullscreen mode

the context provider component

The context provider component is how global state, and its' relevant functions, are provided to other components in a React application.

In the same file as the createContext object, create a context provider component. Assuming function component syntax; the function should take in the component's children as props and return JSX with the parent component encompassing the children props. Set the name of the parent component equal to the createContext object with .Provider added to the end and pass it a value prop. The value prop will hold the global state relevant data being passed to the children components.

Export the createContext object and the context provider component for use in other areas of the application.

import React, {useState} from 'react';

const GlobalContext = React.createContext();

function GlobalProvider({ children }) {
    const [global, setGlobal] = useState(false);

    return (
        <GlobalContext.Provider value={global}>
            {children}
        </GlobalContext.Provider>
    );
};

export default GlobalProvider;
export { GlobalContext };
Enter fullscreen mode Exit fullscreen mode

To make the global state data available to other components in the application, import the context provider component and wrap it around the components that require the global state.

For the purpose of this example, Item is a component rendered in ItemList and needs access to the global variable:

import React from "react";
import Item from "./Item";
import GlobalProvider from '../context/global';


function ItemList() {
  return (
    <div>
      <GlobalProvider>
        <Item />
      </GlobalProvider>
    </div>
  );
};

export default ItemList;
Enter fullscreen mode Exit fullscreen mode

For setting global state, the goal of the provider component object is to house all setState functions related to the global state variable. This minimizes de-bugging time - any changes to a particular state occur will in one file. To separate out the global state from other sections of code, create a context folder and a new file for each separate section of global state. To pass functions that interact with the global state to other components in the application, create an object that holds the global states and their associated functions, and pass the object into the values prop of the context provider component.

import React, { useState } from 'react';

const GlobalContext = React.createContext();

function GlobalProvider({ children }) {
  const [global, setGlobal] = useState(false);

  function handleClick() {
    setGlobal((global) => !global);
    console.log('This is an example function that interacts 
       with the global state variable global');
  };

  const value = {
    global,
    handleClick
  };

  return (
    <GlobalContext.Provider value={value}>
       {children}
    </GlobalContext.Provider>
    );
};

export default GlobalProvider;
export { GlobalContext };

Enter fullscreen mode Exit fullscreen mode

the useContext hook

The useContext hook in React is how components access the global state created.

Import the useContext hook and the createContext object. Destructure the value prop passed to the context provider component and set it equal to the useContext hook with an argument of the createContext object. This will give the component explicit access to any of the global state relevant data passed into the context provider component.

import React, { useContext } from "react";
import { GlobalContext } from '../context/global';

function Item() {
  const { global, handleClick } = useContext(GlobalContext);  

  return (
    <div>
      {global ? <h2>the global state variable is true</h2> 
         : <h2>the global state variable is false</h2>}
      <button onClick={handleClick}>Change the value of 
         global</button>
    </div>
  );
};

export default Item;
Enter fullscreen mode Exit fullscreen mode

Happy global state management!

For more documentation on useContext check out the React Docs documentation: React Docs - Context

Discussion (0)