Quick and Easy React Provider and Context with Hooks Template

While researching the best way to implement React Context into my projects, I found that a lot of the articles were over-complicating what should be a very simple process.

The code below is a slimmed down use case, so you can copy straight into your build. There is a template for setting up the provider and content, and a short note on how it should be used.

I have laid it out so you can copy and paste, find and replace (I am a poet this morning!).

Context is great when props need to be passed up and down component trees. It simplifies the whole process. Some writers argue that context introduces a complicated abstraction, and that prop drilling can sometimes be a better solution. In very simple cases this can be true, but when scaling an application I find it so much easier to just start with Context.

 

Creating the Provider and Hooks

A Provider is the very top level component. It wraps around a particular section of the app that you want to have access to particular state or functions.

In this example it is relatively small, as it is only being used for a adding and removing items to an array.

Everything wrapped up together:

import React, { createContext, useContext, useState } from "react";

const ListContext = createContext([{}, () => {}]);

const ListProvider = ({children}) => {
  const [state, setState] = useState({
    itemList: []
  });

  return ({children})
};

const useListContext = () => {
  const [state, setState] = useContext(ListContext);

  function addItemToList({ item }) {
    setState(state => {
      const newList = [...state.itemList, item];
      return {
        ...state,
        itemList: newList
      };
    });
  }

  function resetList() {
    setState(state => ({
      ...state,
      itemList: []
    }));
  }

  return {
    addItemToList,
    resetList
  };
};

export { ListContext, ListProvider, useListContext };

 

Using Context and Hooks

To use Context in a particular area, you need to wrap the components you want to be included in the Context provider. Then extract the state and run your logic, or include the hooks where needed. A (very very simple) example of this is shown below:

import React from "react";
import { ListProvider, useListContext } from "../ListContext"; // This is the file shown above

const App = () => {
  const { addItemToList, resetList } = useListContext();
  return (
    <ListProvider>
      <div className="wrapper">
        <button onClick={() => addItemToList("This is an item")}>
          Add "This is an item"
        </button>
        </button onClick={() => resetList()}>Remove all items from list</button>
      </div>
    </ListProvider>
  );
};

As long as the ListProvider is used before introducing the hooks, the hooks can be used anywhere within the app. They do not need to be within the same file. Which is the benefit of using this system.