React Context для состояния темы
Создайте ThemeProvider, предоставляющий текущую тему и функцию переключения всему дереву компонентов
«React Context для состояния темы» — бесплатный урок React Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения React Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс React Academy содержит 4 уроков всего.
Создание ThemeContext
Начните с вызова createContext() со значением по умолчанию, соответствующим форме вашего контекста: const ThemeContext = createContext({ theme: 'light', toggleTheme: () => {} }). Значение по умолчанию используется только в том случае, если компонент читает контекст без родительского Provider, что удобно для тестирования изолированных компонентов.
Компонент ThemeProvider
Компонент ThemeProvider — это оболочка, содержащая всю логику темы. При монтировании он считывает системные настройки, управляет состоянием theme, предоставляет функцию toggleTheme и оборачивает дочерние компоненты в ThemeContext.Provider value={{ theme, toggleTheme }}. Разместите его ближе к вершине дерева компонентов.
Использование контекста с помощью useContext
Любой дочерний компонент может получить тему, вызвав useContext(ThemeContext). Этот вызов возвращает текущее значение контекста, включая theme и toggleTheme. При изменении темы компонент автоматически повторно отображается, поэтому значение всегда остаётся синхронизированным без передачи свойств через всю иерархию.
Синхронизация data-theme с DOM
Переменные CSS зависят от атрибута data-theme у корневого элемента. В ThemeProvider добавьте useEffect, который выполняется при каждом изменении theme: document.documentElement.setAttribute('data-theme', theme). Это обеспечивает плавную связь между состоянием React и слоем CSS.
Сохранение переопределения темы пользователем в localStorage
Чтобы сохранять выбор пользователя после перезагрузки страницы, записывайте его в localStorage при каждом изменении темы: localStorage.setItem('theme', theme). Эту логику можно инкапсулировать в пользовательском хуке useLocalStorage, который возвращает пару, аналогичную состоянию, и автоматически сохраняет каждое обновление.
Инициализация темы из localStorage
При инициализации состояния темы сначала прочитайте значение из localStorage: localStorage.getItem('theme'). Если сохранённого значения нет, используйте системные настройки через window.matchMedia('(prefers-color-scheme: dark)').matches как запасной вариант. Эта инициализация выполняется только один раз при монтировании.
Порядок приоритетов темы
Правильный порядок приоритетов от высшего к низшему таков: сохранённое предпочтение пользователя в localStorage, затем системные настройки ОС и наконец жёстко заданное значение по умолчанию, обычно светлая тема. Такой порядок позволяет пользователю сохранять полный контроль и одновременно учитывать настройки ОС, если пользователь явно не выбрал тему в приложении.
Вспомогательный хук useTheme
Прямой вызов useContext(ThemeContext) в каждом компоненте раскрывает детали реализации. Вместо этого экспортируйте хук useTheme: function useTheme() { return useContext(ThemeContext); }. Теперь компоненты импортируют useTheme и вызывают его, не зная о внутреннем контексте.
Предоставление функции переключения
Функция toggleTheme переключает тему между light и dark: setTheme(prev => prev === 'light' ? 'dark' : 'light'). Предоставьте её через контекст, чтобы любая кнопка в дереве компонентов могла вызвать переключение. Состояние хранится в одном месте, а логика переключения используется повсюду.
Мемоизация значения контекста
Объект значения контекста создаётся заново при каждом отображении ThemeProvider. Оберните его в useMemo, чтобы предотвратить ненужные повторные отображения всех потребителей контекста: const value = useMemo(() => ({ theme, toggleTheme }), [theme]). Это распространённая оптимизация производительности для поставщиков контекста.
Тестирование ThemeProvider
В тестах оборачивайте отображаемые компоненты в пользовательскую утилиту renderWithTheme, которая использует ThemeProvider в качестве оболочки. Для изолированного тестирования также можно создать простой имитационный контекст: ThemeContext.Provider value={{ theme: 'dark', toggleTheme: jest.fn() }}. Это позволяет тестировать компоненты в состоянии с определённой темой.
Порядок приоритетов темы
Каков правильный порядок приоритетов при инициализации темы приложения — от высшего к низшему?
Итоги урока: контекст React для состояния темы
Создайте ThemeContext и ThemeProvider, который управляет состоянием темы, синхронизирует его с localStorage и устанавливает data-theme в документе. Для удобного использования применяйте хук useTheme. Порядок приоритетов таков: сохранённое предпочтение, затем системные настройки и наконец значение по умолчанию.
Часто задаваемые вопросы
Урок «React Context для состояния темы» бесплатный?
Да — полный текст урока «React Context для состояния темы» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс React Academy, подпишись на CoddyKit PRO. Курс React Academy содержит 4 уроков всего.
Чему я научусь в уроке «React Context для состояния темы»?
Создайте ThemeProvider, предоставляющий текущую тему и функцию переключения всему дереву компонентов Ты практикуешь React Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать React Academy?
Предыдущий опыт не требуется. React Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «React Context для состояния темы»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке React Academy?
Да. Каждый урок React Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Определение системной цветовой схемы
- Переменные CSS для переключения темы
- React Context для состояния темы
- Сохранение темы и предотвращение мерцания