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
Member discussion