React Context API - an Implementation Quick Guide
Tags: beginners, react, statemanagement, webdev
Published: 2022-06-22 22:19:53

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](https://javascript.works-hub.com/learn/state-management-battle-in-react-hooks-redux-and-recoil-9977a)_

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

## 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 a 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 };
```

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

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

```


## 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;
```

Happy global state management!

For more documentation on useContext check out the React Docs documentation: [React Docs - Context](https://reactjs.org/docs/context.html)