Проверяет понимание проблемы hydration mismatch в SSR/SSG-приложениях и умение безопасно отображать данные из localStorage после гидратации.
При серверном рендеринге (SSR) или статической генерации (SSG) HTML формируется на сервере, где объекта window и localStorage не существует. React при гидратации сравнивает серверный HTML с тем, что рендерит клиент при первом проходе. Если клиент сразу читает localStorage и выводит другое значение, деревья не совпадают — возникает ошибка hydration mismatch.
Нужно разделить два состояния: начальное (одинаковое на сервере и клиенте) и обновлённое (после монтирования). Начальное рендерим всегда, а реальные данные подставляем в useEffect, который выполняется только на клиенте после гидратации.
function ThemeLabel() {
const [theme, setTheme] = useState(null); // одинаково на сервере и клиенте
useEffect(() => {
// выполняется только на клиенте после гидратации
setTheme(localStorage.getItem('theme') || 'light');
}, []);
if (theme === null) return <span>Загрузка...</span>; // нейтральный контент
return <span>Тема: {theme}</span>;
}
Первый клиентский рендер возвращает тот же нейтральный контент, что и сервер, поэтому гидратация проходит без ошибок. После монтирования useEffect читает localStorage и вызывает setState, что приводит к обычному клиентскому ре-рендеру — уже без сверки с сервером.
В Next.js можно использовать dynamic(() => import('./Comp'), { ssr: false }) или компонент-обёртку, который рендерит детей только после mounted. Это тот же принцип: серверный HTML не содержит клиентских данных.
Итог: применяйте этот приём всегда, когда контент зависит от localStorage, cookies, window или других браузерных API — это единственный надёжный способ избежать hydration mismatch в SSR/SSG-приложениях.
Frontend developer
Ментор по Frontend
Полное сопровождение до оффера — без дорогих курсов, с оплатой после трудоустройства
Записаться на консультацию