Что такое гидрация в SSR и какие проблемы с ней возникают?
Server Side Rendering
Гидрация (hydration) — процесс, при котором React «оживляет» серверный HTML: подключает обработчики событий и состояние к уже готовой разметке, не создавая DOM заново.
Как это работает
- Сервер рендерит компоненты в HTML и отправляет его вместе с JS.
- Браузер сразу показывает HTML — пользователь видит контент.
- React загружает JS, рендерит дерево в памяти и сопоставляет его с существующим DOM.
- Если они совпадают, React присоединяет обработчики событий.
hydrateRoot(document.getElementById('root'), <App />);Ошибка гидрации (hydration mismatch)
Если HTML сервера не совпал с тем, что рендерит клиент, React сообщает об ошибке и может перерисовать часть дерева.
Частые причины:
- Нестабильные значения:
Date.now(),Math.random(),new Date()дают разный результат на сервере и клиенте. - Доступ к `window`/`localStorage` в рендере: на сервере их нет.
- Различие времени и локали: форматирование дат и чисел зависит от часового пояса и языка.
- Невалидная разметка:
<div>внутри<p>— браузер перестраивает DOM до гидрации. - Расширения браузера, меняющие HTML.
Как избежать
- Не использовать нестабильные значения при рендере: брать их после монтирования в
useEffect. - Для идентификаторов использовать
useId. - Клиентские данные показывать после гидрации через флаг
mountedилиdynamic(..., { ssr: false }). suppressHydrationWarning— только для заведомо различающегося текста (например, время).
Цена гидрации
Страница выглядит готовой, но не интерактивна, пока не загрузится и не выполнится JS. Для сокращения этой паузы используют потоковый рендеринг и выборочную гидрацию (Suspense), а также серверные компоненты, которые не гидрируются вообще.
Коротко для собеседования
Гидрация присоединяет обработчики к серверной разметке. Если клиентский рендер отличается от серверного (даты, Math.random, window), возникает mismatch; значения, зависящие от клиента, получают после монтирования.