30% offEnding soon
ThemeProviderLoading saved progress…

ThemeProvider

A context provider stores a value above a React subtree so descendants can read it without prop drilling. Implement ThemeProvider and useTheme to share a theme string, React's state setter, and a stable toggle function. The provider must also keep its value object stable when the theme has not changed, which prevents context consumers from receiving a needless new value.

Signature

function ThemeProvider({
  initialTheme?: string, // defaults to 'light'
  children: React.ReactNode,
}): React.ReactNode;

function useTheme(): {
  theme: string;
  setTheme: React.Dispatch<React.SetStateAction<string>>;
  toggleTheme: () => void;
};

Examples

<ThemeProvider initialTheme="dark">
  <Toolbar />
</ThemeProvider>

// Inside Toolbar:
const { theme, toggleTheme } = useTheme();
// theme === 'dark'; toggleTheme() changes it to 'light'.
const { setTheme } = useTheme();
setTheme('sepia');
setTheme((current) => `${current}-contrast`);
// The final theme is 'sepia-contrast'.

Notes

  • Initialize once — use the first initialTheme; changing that prop later must not reset current state.
  • Provide exactly three fields{ theme, setTheme, toggleTheme }; setTheme must be React's setter and accept direct values or updater functions.
  • Toggle deterministicallydark becomes light; every other current string becomes dark. Use a functional state update so batched calls compose.
  • Preserve identity — keep toggleTheme stable and memoize the context value. Its object identity changes only when theme changes.
  • Require a provideruseTheme throws a clear error outside ThemeProvider; nested providers remain independent and the nearest one wins.
  • Keep the scope narrow — add no DOM wrapper, persistence, system-preference lookup, CSS, validation, reducer, or separate contexts.