Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

Документы

Медиа

Назад
Вопрос про JavaScript: hydration, SSR, React, hydration mismatch, server-side rendering

Что такое hydration mismatch и как его избежать?

Вопрос проверяет понимание проблемы несоответствия между серверным и клиентским рендерингом в React и способов её предотвращения для обеспечения стабильности приложения.

Короткий ответ

Hydration mismatch — это ошибка, возникающая, когда HTML, сгенерированный на сервере (SSR), не совпадает с тем, что React пытается отрисовать на клиенте при первой загрузке. React ожидает, что DOM будет идентичным, чтобы "гидратировать" его, добавляя обработчики событий. Основные причины: разное время или данные на сервере и клиенте, использование браузерных API (например, `window`) на сервере. Чтобы избежать, нужно синхронизировать данные, использовать `useEffect` для клиент-специфичного кода и библиотеки типа `next/dynamic` для ленивой загрузки компонентов.

Длинный ответ

Hydration mismatch — это критическая ошибка в React-приложениях, использующих серверный рендеринг (SSR). Она возникает в момент "гидратации", когда React на клиенте пытается "оживить" статический HTML, полученный с сервера, добавляя к нему обработчики событий и состояние. Если DOM-дерево, созданное клиентом, не совпадает побитово с серверным HTML, React не может корректно сопоставить узлы, что приводит к ошибке и полной перерисовке всего поддерева на клиенте, сводя на нет преимущества SSR.

Основные причины несоответствия

  • Разные данные: Сервер и клиент могут использовать разные наборы данных для рендеринга (например, из-за кэширования или асинхронных запросов).
  • Клиент-специфичная логика: Прямое обращение к объектам `window`, `document` или `localStorage` во время рендеринга компонента. На сервере этих объектов нет, поэтому результат будет отличаться.
  • Разное время: Генерация контента, зависящего от текущего времени или случайных значений, без синхронизации.
  • Сторонние библиотеки: Некоторые UI-библиотеки могут по-разному вести себя в среде Node.js и браузера.

Как избежать mismatch

Ключевой принцип — гарантировать, что начальный рендер компонента даёт абсолютно одинаковый результат и на сервере, и на клиенте.

  • Используйте `useEffect` для клиент-специфичного кода: Любые операции, требующие браузерного API, должны выполняться только после монтирования компонента, внутри `useEffect`. Это исключает их влияние на серверный рендер.
  • Синхронизируйте данные: Передавайте с сервера на клиент все необходимые для начального рендера данные (например, через пропсы или глобальное состояние). В Next.js для этого часто используется `getServerSideProps`.
  • Контролируйте рендеринг с помощью состояния: Для компонентов, которые должны выглядеть по-разному на клиенте, используйте флаг `isClient`, который устанавливается в `true` только после монтирования.
  • Используйте ленивую загрузку динамических компонентов: В Next.js компоненты, которые не должны рендериться на сервере, можно обернуть в `next/dynamic` с опцией `ssr: false`.

Пример кода с решением

Рассмотрим компонент, который показывает текущее время, но должен избежать mismatch.

import { useEffect, useState } from 'react';

function TimeComponent() {
  // 1. Инициализируем состояние одинаково для сервера и клиента
  const [currentTime, setCurrentTime] = useState(null);

  useEffect(() => {
    // 2. Код, зависящий от браузера, запускаем ТОЛЬКО на клиенте
    setCurrentTime(new Date().toLocaleTimeString());
  }, []); // Пустой массив зависимостей = запуск только после монтирования

  // 3. На сервере и при первой отрисовке на клиенте показываем заглушку
  return (
    
      Текущее время: {currentTime || 'Загрузка...'}
    
  );
}

export default TimeComponent;

В этом примере на сервере и при самой первой отрисовке на клиенте (во время гидратации) компонент выведет "Загрузка...". Только после монтирования в `useEffect` обновится состояние и покажется реальное время. Так как первоначальный HTML идентичен, mismatch не произойдёт.

Вывод

Hydration mismatch — это проблема целостности данных и логики рендеринга между сервером и клиентом. Избегать её необходимо для сохранения преимуществ SSR: скорости первой загрузки и SEO. Основной подход — чёткое разделение кода: всё, что должно быть в начальном HTML, должно рендериться одинаково, а любая клиент-специфичная логика должна быть изолирована в `useEffect` или инициирована только после гидратации.

Уровень

  • Рейтинг:

    4

  • Сложность:

    5

Навыки

  • JavaScript

    JavaScript

  • React

    React

Ключевые слова

#hydration

#SSR

#React

#hydration mismatch

#server-side rendering

Подпишись на React Developer в телеграм