Gernar
Frontend DeveloperReact и Next.js

Интервью-вопрос

Что такое гидратация

Гидратация связывает серверный HTML с клиентским React, чтобы страница стала интерактивной. Главный риск для фронтенда: первый серверный и клиентский рендер должны совпасть, иначе появятся mismatch-ошибки и нестабильный UI.

Добавлен
Редакция

Подготовьте короткий ответ и пару деталей на случай уточняющих вопросов.

🐰0
🥚0

Мини-квиз

Проверка перед разбором

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

Вопрос 1 из 60 правильно

Как лучше объяснить гидратацию на интервью?

Вы отвечаете коротко и хотите сразу отделить гидратацию от обычного CSR.

Варианты ответа

Разбор

Разобраться, а не зазубрить

Дальше разбираем суть, типичные уточнения и места, где легко сказать лишнее или перепутать термины.

Базовая идея

Гидратация нужна там, где страница сначала рендерится вне браузера, например на сервере, а потом должна стать обычным интерактивным приложением в браузере. Сервер отправляет HTML. Браузер показывает его пользователю. Затем загружается JavaScript, и React сопоставляет свое дерево компонентов с уже существующим DOM.

На интервью не стоит говорить, что React заново рисует всю страницу. Смысл как раз в том, что HTML уже есть. React должен понять, что этот DOM соответствует ожидаемому дереву. После этого он подключает события, состояние и дальнейшие обновления.

Практический вывод простой. SSR улучшает первый показ контента, но до завершения гидратации интерфейс может быть не полностью интерактивным. Например, кнопка уже видна, но обработчик клика еще не подключен.

Как это работает в React и Next.js

В React гидратация обычно происходит через API вроде hydrateRoot. Он работает с контейнером, где уже лежит серверная разметка. Фреймворк, например Next.js, скрывает большую часть этой механики. Но принцип остается тем же: серверный HTML должен совпасть с первым клиентским рендером.

В Next.js важно уточнить модель рендера. В Pages Router и в Client Components App Router интерактивные части проходят клиентскую гидратацию. В App Router Server Components не превращаются в клиентские компоненты с состоянием и обработчиками. Поэтому сильный ответ звучит так: гидратируются именно те части, которым нужен клиентский JavaScript.

Как выбирать подход

1Нужно, чтобы контент был виден до загрузки JavaScript?
Используйте SSR или SSG, затем гидратируйте интерактивные части.
2Компонент содержит состояние, события или browser API?
Это Client Component. Ему нужна клиентская часть и гидратация.
3Первый рендер зависит от `window`, даты или случайного значения?
Сделайте стабильный HTML или перенесите отличие в эффект после гидратации.
4Блок тяжелый и не важен для первого экрана или SEO?
Рассмотрите ленивую загрузку, разделение кода или клиентский рендер только этого блока.

Главная ловушка: разная разметка на сервере и клиенте

Hydration mismatch появляется, когда сервер отдал один HTML, а клиент при первом рендере ожидает другой. Частые причины: текущее время, случайные значения, чтение localStorage, проверка window, разные данные в API или условный рендер по размеру экрана.

Плохой пример: компонент не падает на сервере, но все равно может отрендерить разные значения.

// Плохо: сервер и клиент могут увидеть разные темы на первом рендере.
function ThemeLabel() {
  const theme =
    typeof window !== "undefined"
      ? localStorage.getItem("theme") ?? "light"
      : "light";

  return <span>{theme}</span>;
}

Если у пользователя в браузере сохранена тема dark, сервер отдаст light, а первый клиентский рендер сразу захочет dark. Это и есть риск mismatch.

Более безопасный вариант: сделать первый рендер стабильным, а клиентское значение применить после гидратации. Если тема критична для первого экрана, лучше получить ее на сервере из cookie и отдать сразу правильный HTML.

// Безопаснее: первый рендер стабилен, отличие применяется после гидратации.
function ThemeLabel() {
  const [theme, setTheme] = useState("light");

  useEffect(() => {
    setTheme(localStorage.getItem("theme") ?? "light");
  }, []);

  return <span>{theme}</span>;
}

Этот вариант может дать короткий визуальный переход. Поэтому для темы сайта часто используют cookie, серверную подстановку класса на html или небольшой inline-скрипт до React, если это принято в проекте.

Безопасный поток
  1. 1Сервер отдает HTML с теми же данными, которые нужны первому клиентскому рендеру.
  2. 2Клиент загружает JavaScript, и React строит то же дерево компонентов.
  3. 3React связывает существующий DOM с обработчиками и состоянием.
  4. 4Клиентские отличия применяются после гидратации или явно приходят с сервера.
Опасный поток
  1. 1Сервер отдает HTML с одним состоянием интерфейса.
  2. 2Первый клиентский рендер сразу читает `localStorage`, `window` или текущее время.
  3. 3React получает другой результат и сообщает о mismatch.
  4. 4Пользователь видит скачок UI, потерю обработчиков или непредсказуемые атрибуты.

Практический вывод для фронтенда

На интервью полезно связать определение с реальной работой. Гидратация влияет на то, как вы пишете компоненты для SSR-приложения. Все, что зависит только от браузера, нельзя бездумно использовать во время первого рендера.

Хорошее правило: первый JSX должен быть детерминированным для сервера и клиента. Если данные нужны сразу, получите их на сервере и передайте в компонент. Если данные нужны только после загрузки страницы, читайте их в эффекте и заранее продумайте fallback, чтобы UI не прыгал слишком заметно.

Еще один практический риск связан с производительностью. Большой клиентский бандл делает гидратацию долгой. Пользователь видит страницу, но не может нормально с ней работать. Поэтому в Next.js полезно оставлять больше логики в Server Components, дробить клиентские компоненты и не переносить весь экран под use client без причины.

Отдельно следите за данными. Если HTML уже содержит результат серверного запроса, клиент не должен сразу очищать экран и показывать пустой loading ради такого же запроса. Лучше передать эти данные как начальные, настроить кеш или refetch в фоне. Если запрос зависит от действий пользователя, нужна отмена или проверка актуальности, иначе поздний ответ может перезаписать новый UI.

Что сказать коротко

Можно ответить так:

Гидратация это процесс, в котором React на клиенте подключается к HTML, уже сгенерированному на сервере, и делает его интерактивным. Это отличается от обычного client-side render, где DOM создается на клиенте с нуля. Главная вещь, за которой нужно следить, это совпадение первого серверного и клиентского рендера. Иначе будут hydration mismatch, скачки UI или проблемы с обработчиками. В Next.js особенно важно понимать границу между Server Components и Client Components. Гидратация нужна интерактивной клиентской части.

Частые ошибки

Где обычно ошибаются

Проверьте формулировки, которые звучат уверенно, но на интервью быстро выдают пробелы.

  1. 1

    Называть гидратацию повторным рендером

    Такой ответ теряет главную идею. React не обязан создавать DOM с нуля. Он ожидает уже существующий серверный HTML и связывает его с клиентским деревом. Лучше скажите, что это подключение React к готовому DOM и добавление интерактивности.

  2. 2

    Читать browser API во время первого рендера

    На сервере нет window, localStorage и реального viewport. Если первый клиентский JSX отличается от серверного, появится hydration mismatch. Безопаснее дать стабильное начальное состояние, а browser API читать в useEffect или передавать значение с сервера.

  3. 3

    Игнорировать warning о mismatch

    Предупреждение не всегда означает только косметическую проблему. У пользователя могут не сработать обработчики, измениться текст, остаться старые атрибуты или появиться скачок интерфейса. На интервью лучше показать, что вы ищете причину расхождения, а не просто подавляете warning.

  4. 4

    Обещать мгновенную интерактивность после SSR

    SSR дает ранний HTML, но JavaScript еще должен загрузиться, выполниться и пройти гидратацию. На слабых устройствах пользователь может видеть кнопку, которая пока не реагирует. Поэтому важны размер клиентского бандла, разбиение кода и аккуратная работа с тяжелыми компонентами.

  5. 5

    Отключать SSR как первое решение

    Клиентский рендер проблемного блока может скрыть mismatch, но ухудшить первый экран, SEO и UX. Это нормальный прием для виджетов, которые зависят только от браузера и не важны до загрузки JS. Для основного контента лучше исправить источник расхождения.

  6. 6

    Сразу заново запрашивать данные после SSR

    Если сервер уже отдал HTML со списком товаров, а клиент на первом экране сразу сбрасывает его в loading и делает тот же запрос, пользователь видит скачок UI и тратит лишнюю сеть. Еще хуже, если поздний ответ перетрет более свежие данные. Безопаснее передать начальные данные в клиентский кеш, не показывать пустой loading поверх готового контента и отменять устаревшие запросы, если компонент все же делает refetch.

Follow-up

Что могут спросить дальше

Короткие ответы на вопросы, которыми проверяют понимание гидратации, SSR и поведения React в браузере.

Живые ответы

Видео с похожим вопросом

Если найдем публичные интервью с таким вопросом, добавим их сюда. Их удобно смотреть после теории, чтобы свериться с живыми ответами.

Пока видео нет. Когда появятся подходящие публичные интервью, добавим их в этот блок, чтобы можно было сравнить разбор с тем, как отвечают реальные кандидаты.

Содержание