← Каталог
React — компоненты-рецепты — Тёмная тема через Context
Фрагмент из «React — компоненты-рецепты»: Тёмная тема через Context.
import { createContext, useContext, useMemo, useState } from 'react';
const ThemeContext = createContext(null);
export function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');
const value = useMemo(
() => ({
theme,
toggle: () => setTheme((t) => (t === 'light' ? 'dark' : 'light')),
}),
[theme]
);
return (
<ThemeContext.Provider value={value}>
<div className={`app theme-${theme}`}>{children}</div>
</ThemeContext.Provider>
);
}
export function useTheme() {
const ctx = useContext(ThemeContext);
if (!ctx) throw new Error('useTheme вызывают вне ThemeProvider');
return ctx;
} import { createContext, useContext, useMemo, useState } from 'react';
const ThemeContext = createContext(null);
export function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');
const value = useMemo(
() => ({
theme,
toggle: () => setTheme((t) => (t === 'light' ? 'dark' : 'light')),
}),
[theme]
);
return (
<ThemeContext.Provider value={value}>
<div className={`app theme-${theme}`}>{children}</div>
</ThemeContext.Provider>
);
}
export function useTheme() {
const ctx = useContext(ThemeContext);
if (!ctx) throw new Error('useTheme вызывают вне ThemeProvider');
return ctx;
} import { ThemeProvider, useTheme } from './theme/ThemeContext';
function Toolbar() {
const { theme, toggle } = useTheme();
return (
<button type="button" onClick={toggle}>
Тема: {theme}
</button>
);
}
export default function App() {
return (
<ThemeProvider>
<Toolbar />
<main>Контент страницы</main>
</ThemeProvider>
);
} import { ThemeProvider, useTheme } from './theme/ThemeContext';
function Toolbar() {
const { theme, toggle } = useTheme();
return (
<button type="button" onClick={toggle}>
Тема: {theme}
</button>
);
}
export default function App() {
return (
<ThemeProvider>
<Toolbar />
<main>Контент страницы</main>
</ThemeProvider>
);
}