createStaticRouter — это функция из библиотеки React
Router, предназначенная для конфигурации маршрутов в приложениях, где не
требуется динамическое изменение URL через браузер. Она особенно полезна
для серверного рендеринга (SSR) и генерации статических сайтов. Основная
идея заключается в том, чтобы заранее определить дерево маршрутов и их
соответствующие компоненты, а затем передавать это дерево в
маршрутизатор.
Для начала необходимо импортировать функцию:
import { createStaticRouter, RouterProvider } from "react-router-dom/server";
createStaticRouter принимает два аргумента:
Простейший пример:
const routes = [
{
path: "/",
element: <HomePage />,
},
{
path: "/about",
element: <AboutPage />,
},
];
const staticRouter = createStaticRouter(routes);
<RouterProvider router={staticRouter} />
Здесь RouterProvider принимает созданный статический
маршрутизатор и обеспечивает рендеринг компонентов в зависимости от
URL.
Каждый маршрут описывается объектом со следующими ключами:
Пример вложенных маршрутов:
const routes = [
{
path: "/",
element: <Layout />,
children: [
{
path: "",
element: <HomePage />,
},
{
path: "profile",
element: <ProfilePage />,
},
],
},
];
В этом примере Layout рендерится всегда, а содержимое
меняется в зависимости от дочернего маршрута.
loader для предварительной загрузки данныхСтатический маршрутизатор позволяет загружать данные перед рендерингом страницы:
const routes = [
{
path: "/users/:id",
element: <UserPage />,
loader: async ({ params }) => {
const response = await fetch(`https://api.example.com/users/${params.id}`);
return response.json();
},
},
];
Внутри компонента можно использовать хук
useLoaderData:
import { useLoaderData } from "react-router-dom";
function UserPage() {
const user = useLoaderData();
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
);
}
errorElementЕсли loader или action выбрасывают ошибку,
можно отобразить специальный компонент:
const routes = [
{
path: "/users/:id",
element: <UserPage />,
loader: async ({ params }) => {
const response = await fetch(`https://api.example.com/users/${params.id}`);
if (!response.ok) throw new Error("Пользователь не найден");
return response.json();
},
errorElement: <ErrorPage />,
},
];
Компонент ErrorPage получит объект ошибки через хук
useRouteError.
createStaticRouterВторой аргумент функции позволяет задавать дополнительные настройки:
Пример с базовым путем:
const staticRouter = createStaticRouter(routes, { basename: "/app" });
createStaticRouter идеально подходит для SSR:
import express from "express";
import { renderToString } from "react-dom/server";
import { RouterProvider, createStaticRouter } from "react-router-dom/server";
const app = express();
app.get("*", async (req, res) => {
const router = createStaticRouter(routes, { initialEntries: [req.url] });
const html = renderToString(<RouterProvider router={router} />);
res.send(`<!DOCTYPE html><html><body>${html}</body></html>`);
});
app.listen(3000);
Здесь initialEntries задаёт URL для рендеринга, что
позволяет серверу корректно отобразить нужную страницу без клиентской
навигации.
loader.errorElement.basename).createStaticRouter предоставляет строгую, декларативную
структуру маршрутов, которая делает серверный рендеринг и генерацию
статических страниц безопасной, предсказуемой и удобной для
масштабирования сложных приложений.