How to use React Context with Hooks & TypeScript

How to use React Context with Hooks & TypeScript

Straightforward and clean

Table of contents

Although I don’t reach for React Context all the time, there are some use cases where it can be a great tool. Recently, I had to use them in a TypeScript project with Hooks, and struggled for a bit.

Counter Context

I’ll demonstrate how to write a React Context in a clean and straightforward way with a Counter component. This component will work like this:

From React documentation, we first need to use createContext in order to define a context (with default values). As we are using TypeScript, we also need to define its shape.

Let’s create a CounterContext.tsx file:

import { createContext } from 'react';

type ContextType = {
  increment: () => void;
  counter: number;
};

export const CounterContext = createContext<ContextType>({
  increment: () => {},
  counter: 0
});

Once defined, we are able to create a CounterContextProvider that will be responsible for:

  • Storing the Counter state.

  • Handling the Increment operation.

Let’s write and export it:

import { createContext, useCallback, useState } from "react";

type ContextType = {
  increment: () => void;
  counter: number;
};

export const CounterContext = createContext<ContextType>({
  increment: () => {},
  counter: 0,
});

const CounterContextProvider: React.FC = ({ children }) => {
  const [counter, setCounter] = useState(0);

  const increment = useCallback(() => {
    setCounter((previousCounter) => previousCounter + 1);
  }, []);

  return (
    <CounterContext.Provider value={{ counter, increment }}>
      {children}
    </CounterContext.Provider>
  );
};

export default CounterContextProvider;

Now we can create a Counter.tsx file with a Counter Component and add both Counter and CounterContextProvider in our App.

For ReactJS:

import React from 'react';
import ReactDOM from 'react-dom';

import Counter from './Counter';
import CounterContextProvider from './CounterContext';

ReactDOM.render(
  <React.StrictMode>
    <CounterContextProvider>
      <Counter />
    </CounterContextProvider>
  </React.StrictMode>,
  document.getElementById('root')
);

We can then implement our Counter component with useContext the easy way:

import { useContext } from "react";
import { CounterContext } from "./CounterContext";

const Counter: React.FC = () => {
  const { increment, counter } = useContext(CounterContext);

  return (
    <>
      <h1>Counter : {counter}</h1>
      <button onClick={increment}>Increment</button>
    </>
  );
};

export default Counter;

Conclusion

And there we have it! Hopefully, you now know how to use React Context a little better.


Cover photo by mohammadtkh on Unsplash