How to Manage State by Using the React Context API

When I work on large-scale applications, I use Redux for state management. However, when it comes to building smaller applications and smaller personal projects, Redux can feel cumbersome. So, what’s the best light-weight solution for state management of these smaller applications? React hooks work really well for smaller applications, but sometimes you need to share state between components, and passing that state through components via props can get a little clunky. That’s where React Context comes to the rescue.

By utilizing the React Context API, you can avoid prop drilling. It also helps keep your components cleaner and simpler.

Let’s walk through what this would look like if we’re adding React Context to an application. First, I like to organize my context within a contexts folder within the src directory. Then I create a context file where all the global state will live. For this example, let’s call the file ItemContext.js:

import { createContext, useState } from "react";
import PropTypes from "prop-types";
const ItemContext = createContext();
const ItemProvider = ({ children }) => {
  const [items, setItems] = useState([]);
  const addItem = (item) => {
    const index = items[items.length - 1].id + 1;
    item.id = index;
    const updatedItems = [...items, item];
    setItems(updatedItems);
  };
  const editItem = (id, item) => {
    const index = items.findIndex((e) => e.id === id);
    const updatedItems = [...items];
    updatedItems[index] = item;
    setItems(updatedItems);
  };
  const removeItem = (id) => {
    const updatedItems = [...items];
    setItems(updatedItems.filter((item) => item.id !== id));
  };
  const context = {
    addItem,
    editItem,
    items,
    removeItem,
  };
  return <ItemContext.Provider value={context}>{children}</ItemContext.Provider>;
};
export { ItemContext, ItemProvider };
ItemProvider.propTypes = {
  children: PropTypes.object,
};

Next, within the src directory, if you don’t already have a hooks directory, create one where we’ll add a new hook file, useItemContext.js:

import { useContext } from "react";
import { ItemContext } from "../contexts/ItemContext";
const useItemContext = () => {
  return useContext(ItemContext);
};
export default useItemContext;

This file probably looks fairly small, but it will help us cut back on copying and pasting the same lines of code when we want to reference this global state. Now, when we want to access the global state or update the state via various components, we can do so by importing the context hook:

import useItemContext from "../hooks/useItemContext";
const ExampleComponent = () => {
  const { addItem, editItem, removeItem } = useItemContext();
  const handleAdd = (item) => {
    addItem(item);
  };
  const handleRemove = () => {
    removeItem(item.id);
  };
  const handleSave = (item) => {
    editItem(item.id, item);
  };
  return (
    {Add your presentation logic here}
  );
};
export default ExampleComponent;

A Brief Overview of React.js

React is a user interface library that was developed at Facebook. React is written in different components and follows the principles of immutable data. It’s often used in enterprise applications, and it makes creating single page applications easier since they have a higher speed thanks to the virtual DOM. This means it writes to the browser DOM only when it is needed, instead of re-rendering an entire view when a change is made.

Virtual DOM

React creates an in-memory DOM where it only renders different parts of the DOM when a change occurs.

JSX

React utilizes JSX, which is a JavaScript extension syntax that allows you to quote HTML.

Babel

Babel is a transpiler that transpiles JavaScript code. It works for JSX as well as ES6 and beyond. Babel converts React’s JSX and ES6 to something the browser can use.

Components

React applications consist of a collection of components. Components are small user interface elements that display data as it changes over time. Used together, these components create entire user interfaces.

Component Lifecycle

Component lifecycles allow you to add libraries and load data at specific times. They also help improve the speed of an application, with lifecycle methods that you can override to run code a specific times in the process.

Mounting methods are called when an instance of a component is being created:

  • getInitialState()
  • componentWillMount()
  • componentDidMount()

Updating methods occur when a change happens to props or state:

  • componentWillReceiveProps()
  • shouldComponentUpdate()
  • componentWillUpdate()
  • render()
  • componentDidUpdate()

Unmounting methods are called when a component is being removed:

  • componentWillUnmount()

 

Deploying a React App to GitHub Pages

Earlier today, I worked on putting together this Sticky Note App, in an effort to get more comfortable with React.js. The application uses React.js, React DOM, and React Draggable.

After completing my application, I was about to tackle deployment with Heroku, since I’ve become pretty familiar with deploying various applications that consist of different stacks on Heroku.

However, this application was a lot simpler, so it seemed like using Heroku would have been a little excessive, especially since there’s no backend component for this application.

So I decided to tackle deploying the application via GitHub pages – which is already one of my favorite ways to deploy simple applications since I host all my repos there as well.

The first step I did, was use the create-react-app command in my terminal, where I then moved the various components of my simple React application. Then I followed the following steps:

Step 1

Edit package.json by adding a homepage

"homepage": "https://[insert username].github.io/[insert project repo name]"

Step 2

Run npm install --save-dev gh-pages

Step 3

Edit package.json by adding a predeploy and deploy script:

"scripts": {
"predeploy": "npm run build",
"deploy": "gh-pages -d build"
}

Step 4

Run: npm run deploy

And there you have it, a simple enough solution for deploying those simple enough React applications.