Гидратация на клиенте

Гидратация — это процесс, при котором статически сгенерированная на сервере HTML-страница «оживляется» на клиенте, превращаясь в полноценное интерактивное приложение. В контексте TanStack Router гидратация позволяет использовать маршруты, которые были предварительно обработаны на сервере, сохраняя при этом состояние и данные, полученные во время серверного рендеринга (SSR).


Основные принципы гидратации

  1. Синхронизация состояния маршрутов TanStack Router хранит дерево маршрутов и состояние каждой ветви. При серверной генерации маршрутов создаётся структура, которая включает:

    • активные маршруты;
    • параметры URL;
    • данные, загруженные через загрузчики (loader);
    • состояние компонентов и вложенных маршрутов.

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

  2. Загрузка данных на клиенте Даже если сервер сгенерировал HTML с данными, TanStack Router может дополнительно выполнять повторные загрузки данных в случае:

    • навигации пользователя на новый маршрут после гидратации;
    • устаревания кешированных данных;
    • специальных условий, указанных в конфигурации маршрута (например, loader с опцией clientOnly: true).

Настройка гидратации

  1. Импорт необходимых модулей Для клиентской гидратации требуется подключение базового маршрутизатора и элементов React:

    import { RouterProvider } from '@tanstack/react-router';
    import { router } from './router';
    import { hydrateRoot } from 'react-dom/client';
    import React from 'react';
    import App from './App';
  2. Инициализация на клиенте Гидратация выполняется с помощью hydrateRoot, где RouterProvider получает уже сконфигурированный маршрутизатор:

    hydrateRoot(
      document.getElementById('root'),
      
        
      
    );

    Здесь важно, чтобы структура маршрутов на сервере и клиенте полностью совпадала, иначе TanStack Router выдаст предупреждения о несоответствии состояния.


Управление состоянием маршрутов

TanStack Router предоставляет возможность сохранять и восстанавливать состояние маршрутов, чтобы гидратация была максимально прозрачной. Основные методы:

  • router.hydrate(state) — позволяет вручную передать состояние маршрутизатора, например, из серверного рендеринга.
  • router.getState() — извлекает текущее состояние маршрутов для передачи на клиент.

Пример передачи состояния с сервера:

// server.js
const state = router.getState();
res.send(`
  
${html}
`);
// client.js
router.hydrate(window.__ROUTER_STATE__);

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


Оптимизация гидратации

  1. Минимизация повторных загрузок Использование loader с поддержкой кеширования или defer-опции позволяет на клиенте пропускать загрузку данных, которые уже были получены на сервере.

  2. Изоляция клиентских эффектов Компоненты могут содержать побочные эффекты, которые должны выполняться только после гидратации. Для этого TanStack Router предлагает проверку:

    import { useIsHydrated } from '@tanstack/react-router';
    
    function Component() {
      const isHydrated = useIsHydrated();
    
      React.useEffect(() => {
        if (isHydrated) {
          // код, который выполняется только после гидратации
        }
      }, [isHydrated]);
    
      return 
    Контент
    ; }
  3. Асинхронная гидратация Для больших приложений можно разделять гидратацию на части, используя ленивую загрузку маршрутов (lazy), чтобы ускорить интерактивность страницы:

    const LazyRoute = React.lazy(() => import('./LazyRoute'));
    
    const router = createRouter({
      routes: [
        {
          path: '/lazy',
          component: LazyRoute,
        },
      ],
    });

Отладка и диагностика

  • Проверка совпадения состояния на сервере и клиенте через router.getState() и вывод консоли помогает выявить несоответствия.
  • TanStack Router выводит предупреждения при расхождении URL, параметров или состояния данных, что критично для корректной гидратации.
  • Использование DevTools для React позволяет отслеживать повторные рендеры и подтверждать, что данные не запрашиваются повторно.

Особенности работы с вложенными маршрутами

TanStack Router автоматически управляет деревом вложенных маршрутов, сохраняя состояние каждой ветви. Важно учитывать:

  • Каждая вложенная ветвь должна иметь уникальный идентификатор (id) и соответствовать структуре на сервере.
  • Гидратация выполняется по всей иерархии, начиная с корневого маршрута, что предотвращает «мигание» интерфейса.
  • Вложенные маршруты могут иметь собственные loader и action, которые синхронизируются при гидратации с клиентской стороны.