createStaticHandler

createStaticHandler — это функция из React Router, предназначенная для работы с маршрутизацией на стороне сервера. Она позволяет создавать обработчики маршрутов, которые могут использоваться для предрендеринга страниц, генерации статических данных или серверного рендеринга (SSR). В отличие от клиентской маршрутизации, где переход между страницами происходит динамически в браузере, createStaticHandler обеспечивает заранее вычисленные результаты для конкретного URL.


Основные возможности

  • Предрендеринг маршрутов: позволяет определить, какие компоненты и данные должны быть загружены для конкретного маршрута без необходимости запуска клиентской логики.
  • Сбор данных на сервере: дает возможность получить данные для всех маршрутов до того, как будет сформирован HTML.
  • Совместимость с React Router Loader/Action: поддерживает загрузку данных через функции loader и обработку действий через action, что делает серверный рендеринг более согласованным с клиентской логикой.

Синтаксис

import { createStaticHandler } from "react-router-dom/server";

const staticHandler = createStaticHandler(routes);
  • routes — массив объектов маршрутов, где каждый объект может содержать следующие свойства:

    • path — путь маршрута.
    • element — компонент, который должен отрендериться для этого маршрута.
    • loader — функция для предзагрузки данных.
    • action — функция для обработки действий (например, формы).
    • children — вложенные маршруты для составных маршрутов.

Пример использования

import { createStaticHandler } from "react-router-dom/server";
import routes from "./routes";

const handler = createStaticHandler(routes);

const url = "/posts/123";

const context = await handler.query(url);

console.log(context);

В этом примере:

  • query(url) — метод, который возвращает объект с информацией о совпавшем маршруте, результатах загрузки данных (loader) и действиях (action).

  • context содержит следующие ключи:

    • matches — массив совпавших маршрутов с параметрами.
    • loaderData — результаты выполнения всех loader для совпавших маршрутов.
    • actionData — результаты выполнения action, если был POST-запрос.
    • error — объект ошибки, если произошла ошибка во время загрузки данных.

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

При работе с вложенными маршрутами createStaticHandler строит дерево совпадений. Каждое совпадение включает:

  • route — объект маршрута, соответствующий текущему уровню дерева.
  • params — объект с параметрами маршрута, извлеченными из URL.
  • pathname — часть пути, соответствующая маршруту.

Например:

const routes = [
  {
    path: "/",
    element: <Root />,
    children: [
      {
        path: "posts",
        element: <Posts />,
        children: [
          { path: ":id", element: <PostDetail />, loader: fetchPost }
        ]
      }
    ]
  }
];

Для URL /posts/42 matches будет содержать три уровня: /, posts и :id. loaderData будет содержать результаты выполнения fetchPost для id = 42.


Обработка ошибок

createStaticHandler поддерживает глобальные и локальные обработчики ошибок. Если любой loader или action выбрасывает ошибку, она будет доступна в context.error. Это позволяет создавать страницу ошибки на сервере до рендеринга HTML:

try {
  const context = await handler.query("/posts/999");
  if (context.error) {
    console.error("Ошибка загрузки данных:", context.error);
  }
} catch (err) {
  console.error("Фатальная ошибка маршрутизации:", err);
}

Интеграция с серверным рендерингом

При SSR createStaticHandler используется вместе с renderToString или renderToPipeableStream для генерации HTML:

import { renderToString } from "react-dom/server";
import { StaticRouterProvider } from "react-router-dom/server";

const context = await handler.query("/posts/42");

const html = renderToString(
  <StaticRouterProvider
    context={context}
    router={handler}
  />
);
  • StaticRouterProvider получает context, чтобы корректно передать данные и маршруты в компоненты React.
  • Данные из loaderData можно использовать для начальной инициализации состояния на клиенте.

Ключевые моменты

  • createStaticHandler — центральный инструмент для предрендеринга маршрутов в React Router.
  • Позволяет работать с loader и action на сервере, что делает SSR и генерацию статических страниц единообразной с клиентской логикой.
  • Поддерживает вложенные маршруты и дерево совпадений.
  • Обеспечивает обработку ошибок на серверной стороне, что улучшает UX и стабильность приложения.
  • Интегрируется с StaticRouterProvider для генерации HTML.

Использование createStaticHandler является эффективным способом для построения приложений с серверной генерацией страниц и статическим рендерингом, сохраняя при этом полную совместимость с механизмами маршрутизации React Router на клиенте.