Command Palette

Search for a command to run...

Hectal
Back to the lesson: Topic 12.5 — Typing Context and Custom Hooks
React · Example 3 of 3

Forgetting the provider: the guard hook's clear error

TypeScript can't know at compile time whether a provider will be above Badge, so the guard turns the mistake into a run-time error with a message that says exactly what to do. Wrap the app in <ThemeContext value={{ mode: "dark" }}> and it renders. Without the guard (and with a {} as Theme default), mode would silently be undefined.

Create context as createContext<Value | null>(null) and read it through a guard hook that throws outside the provider, so callers never see null; return tuples from custom hooks as const, and make hooks generic when the caller decides the type.

Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.

Ready for more? This phase has 5 hands-on exercises with automatic checks.

Practice questions

Write the code in the editor, run it, then open the model answer to compare.

01

Create a typed CartContext with items: string[], add(item: string) and count: number, a CartProvider, and a guard hook useCart. Show the count in a header and an Add button in another component.

02

Write a generic hook useList<T>(initial: T[]) that returns { items, add, removeAt }, and use it with numbers and with objects.

Explain it without notes

01

Why use createContext<Value | null>(null) instead of createContext({} as Value)?

02

What does a guard hook do, and how does it change the type callers see?

03

Why does a custom hook returning [value, setter] need as const?

04

How does TypeScript decide T in a generic hook like useStoredState<T>(key, initial)?

Forgetting the provider: the guard hook's clear error

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

Uncaught Error: useTheme must be used inside <ThemeContext value={...}>
An error occurred in the <Badge> component.

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://react.dev/link/error-boundaries to learn more about error boundaries.