1 min read

React Context example, with Typescript

Here is a step by step walkthrough of using React Context API with Typescript:

Step 1: Create the context

First, you want to define the type of the data you will store inside your context. Next, you can pass it as the generic type to createContext:

type DummyContextType = {
  id?: string;
};
const DummyContext = createContext<DummyContextType>({});

Step 2: Wrap your tree in the Provider

Figure out the common ancestor of the components that need to access the value in the Context and wrap it with the Provider:

const SomeComponentInYourTree: React.FC<PropsWithChildren> = ({ children }) => {
  const inputId = useId();
  return (
    <DummyContext.Provider value={{ id: inputId }}>
      <div>{children}</div>
    </DummyContext.Provider>
  );
};

Step 3: Use the context

You can read from the context using the useContext hook:

export const DeeplyNestedComponent: React.FC<PropsWithChildren> = ({ children }) => {
  const { id } = useContext(DummyContext);
  return <label htmlFor={id}>{children}</label>;
};

Bonus: Handling default values

You noticed that when defining the type above, we made id optional, so that Typescript also accepts the default value of the Context when used outside of the Provider.
But what if you don't want to allow it? You know in your real application the value will always be set, so you don't want to have to let the id as undefined.

First, this is how the updated context definition will look:

type DummyContextType = {
  id: string;
};

const DummyContext = createContext<DummyContextType | null>(null);

Next, we'll wrap the useContext hook with a custom hook and throw an error if no provider is found:

function useDummyContext() {
  const context = useContext(DummyContext);

  if (context === null) {
    // checking for "null" because that's the default value passed in createContext 
    throw new Error("useDummyContext must be used within a DummyContext.Provider");
  }

  return context;
}

Last, we can update how the context is used:

export const DeeplyNestedComponent: React.FC<PropsWithChildren> = ({
  children,
}) => {
  const { id } = useDummyContext();
  return <label htmlFor={id}>{children}</label>;
};

Checkout the working source code for this example over at: https://codesandbox.io/p/sandbox/gh7crt

Get the React Practice Calendar!

28 days of focused practice of increasing difficulty, going through everything from Fundamentals, Data fetching, Forms and using Intervals in React.

You will also get notified whenever a new challenge is published.