Skip to main content

React Context

When progressing in the development process, it's likely that you'll be passing more and more props down to different components, because you'll need the same data in multiple places. At this point, a form of state management would be useful. React Context provides a way to pass data through the component tree without having to pass props down manually at every level. Examples of 'global' data are authenticated user information, the current theme, or a preferred language. When working on TaskFlow, it could be useful to store things like time entries and clients in one central place, because this data will be used in multiple components.

Creating a Context Provider

The first step of using Context is creating a Context Provider. You wrap this Provider around a component tree, and every component in that tree (no matter how deeply nested) can access the stored data.

src/app/StoreContext.tsx
"use client"

import React, { createContext, useState, Dispatch, SetStateAction } from "react";

import * as Types from "../types/types";

interface StoreProviderProps {
children: ReactNode | ReactNode[]
}

interface StoreContextProps {
timeEntries: Types.TimeEntry[],
setTimeEntries: Dispatch<SetStateAction<Types.TimeEntry[]>>
}

export const StoreContext = createContext<StoreContextProps>({} as StoreContextProps);

export function StoreProvider({ children }: StoreProviderProps) {
const [timeEntries, setTimeEntries] = useState([])
const store = {
timeEntries,
setTimeEntries
};

return <StoreContext.Provider value={store}>{children}</StoreContext.Provider>;
}

Next, import this StoreProvider component in src/app/providers.tsx and wrap it around the ThemeProvider if you want to be able to access this Provider everywhere. Of course you could also wrap it around a smaller component tree, if you only want to use Context for that specific part of your application.

info

The React context provider currently isn't supported in React server components.

Using Context

Now if you want to access or change the stored data somewhere in your app, you first need to import the StoreContext component. Using React's useContext hook, you can access the stored state. Again, make sure you're using the hook in a client component and not in a server component.

const { timeEntries, setTimeEntries } = useContext(StoreContext);

React Context is pretty easy to use, but make sure you don't overuse it. It can make component reuse more difficult. Also, every time the value of the context changes, all components related to this context will rerender. In larger apps this can cause performance issues, so sometimes you're better off using a state management library instead, such as Zustand.

Further reading