Context API — встроенный механизм React для передачи данных между компонентами без необходимости пробрасывать их через props на каждом уровне. В библиотеке MUI (Material-UI) Context API часто используется для управления темами, локализацией, состоянием компонентов и глобальными настройками интерфейса.
MUI предоставляет собственные контексты, такие как
ThemeProvider, CssBaseline и
LocalizationProvider, которые реализуют Context API под
капотом. Понимание работы Context API позволяет гибко интегрировать
пользовательские темы и состояния.
ThemeProvider — это компонент-контейнер, через
который передается объект темы (theme) во все дочерние
компоненты. Это позволяет использовать MUI-компоненты с единым стилевым
оформлением.
Пример создания и подключения темы:
import { createTheme, ThemeProvider } from '@mui/material/styles';
import Button from '@mui/material/Button';
const theme = createTheme({
palette: {
primary: {
main: '#1976d2',
},
secondary: {
main: '#dc004e',
},
},
});
function App() {
return (
<ThemeProvider theme={theme}>
<Button color="primary">Primary Button</Button>
</ThemeProvider>
);
}
Ключевые моменты:
createTheme.ThemeProvider автоматически
получает доступ к теме через useTheme или
styled.useTheme позволяет получать текущую тему внутри функциональных компонентов:
import { useTheme } from '@mui/material/styles';
function MyComponent() {
const theme = useTheme();
return <div style={{ color: theme.palette.primary.main }}>Hello MUI</div>;
}
styled — утилита для создания стилизованных компонентов с доступом к теме:
import { styled } from '@mui/material/styles';
import Button from '@mui/material/Button';
const MyButton = styled(Button)(({ theme }) => ({
backgroundColor: theme.palette.secondary.main,
color: '#fff',
'&:hover': {
backgroundColor: theme.palette.secondary.dark,
},
}));
Иногда требуется передавать состояние или настройки, которые не входят в стандартную тему MUI. Для этого создают собственный контекст:
import React, { createContext, useContext, useState } from 'react';
const AppSettingsContext = createContext();
export function AppSettingsProvider({ children }) {
const [darkMode, setDarkMode] = useState(false);
const toggleDarkMode = () => setDarkMode(prev => !prev);
return (
<AppSettingsContext.Provider value={{ darkMode, toggleDarkMode }}>
{children}
</AppSettingsContext.Provider>
);
}
export const useAppSettings = () => useContext(AppSettingsContext);
Использование контекста в компоненте:
import { useAppSettings } from './AppSettingsProvider';
import Switch from '@mui/material/Switch';
function DarkModeToggle() {
const { darkMode, toggleDarkMode } = useAppSettings();
return <Switch checked={darkMode} onCha nge={toggleDarkMode} />;
}
Преимущества:
Можно комбинировать контекст и MUI-тему для динамического изменения стиля приложения:
import { createTheme, ThemeProvider } from '@mui/material/styles';
import { useAppSettings } from './AppSettingsProvider';
function ThemedApp({ children }) {
const { darkMode } = useAppSettings();
const theme = createTheme({
palette: {
mode: darkMode ? 'dark' : 'light',
primary: { main: '#1976d2' },
},
});
return <ThemeProvider theme={theme}>{children}</ThemeProvider>;
}
Таким образом, переключение darkMode автоматически
обновляет тему во всех дочерних компонентах без дополнительной
логики.
MUI предоставляет LocalizationProvider для работы с
локализацией, например, при использовании DatePicker:
import { LocalizationProvider } from '@mui/x-date-pickers';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import ruLocale from 'date-fns/locale/ru';
function App() {
return (
<LocalizationProvider dateAdapter={AdapterDateFns} adapterLocale={ruLocale}>
{/* DatePicker и другие компоненты */}
</LocalizationProvider>
);
}
Использование Context API здесь обеспечивает глобальную доступность локали для всех компонентов, использующих даты.
Часто необходимо использовать несколько контекстов одновременно: тему, настройки и локализацию. Для этого создают “композитный провайдер”:
function AppProviders({ children }) {
return (
<AppSettingsProvider>
<ThemedApp>
<LocalizationProvider dateAdapter={AdapterDateFns}>
{children}
</LocalizationProvider>
</ThemedApp>
</AppSettingsProvider>
);
}
Порядок вложенности важен: компоненты должны быть обернуты в нужный контекст до их использования.
MUI-компоненты полностью поддерживают Context API. Через контекст можно:
ThemeProvider +
useTheme).styled или
sx.LocalizationProvider).Совет по архитектуре: контексты должны быть максимально узко направленными и не перегружать приложение, чтобы избежать лишних перерендеров.
Context API перерендеривает все компоненты-потребители при изменении значения. Чтобы снизить нагрузку:
useMemo) для объектов
и функций:const contextValue = useMemo(() => ({
darkMode,
toggleDarkMode,
}), [darkMode]);
useContext только там, где
это необходимо.Такой подход обеспечивает масштабируемость, поддерживаемость и полную интеграцию с компонентами MUI, сохраняя гибкость React Context API.