'use client'; import { createContext, useContext, useEffect, useState } from 'react'; const ThemeContext = createContext({ dark: false, toggle: () => {} }); export const useTheme = () => useContext(ThemeContext); export function ThemeProvider({ children }) { // Инлайн-скрипт в layout.jsx уже выставляет класс "dark" на ДО гидратации // (чтобы не было мигания темы). Читаем этот класс напрямую при монтировании. const [dark, setDark] = useState(() => { if (typeof document === 'undefined') return false; return document.documentElement.classList.contains('dark'); }); // Побочные эффекты (DOM-класс, localStorage) вынесены в отдельный useEffect, // а не в апдейтер состояния - React может вызвать функцию апдейтера больше // одного раза за один рендер, и тогда classList.toggle сработал бы дважды, // фактически отменяя переключение (баг "не срабатывает" / "снова светлая"). useEffect(() => { document.documentElement.classList.toggle('dark', dark); try { localStorage.setItem('ts-theme', dark ? 'dark' : 'light'); } catch (e) { // localStorage unavailable - theme just won't persist } }, [dark]); return ( setDark((d) => !d) }}> {children} ); }