В TanStack Router маршруты могут быть определены как статически, так и динамически. Динамическая регистрация маршрутов позволяет добавлять новые маршруты во время выполнения приложения, что особенно полезно при построении больших SPA с модульной архитектурой или при загрузке маршрутов по мере необходимости, например, из API или конфигурационных файлов.
Маршрут (Route) в TanStack Router представляет собой объект с набором обязательных и опциональных свойств:
path — строка маршрута, поддерживает параметры
(/users/:id).component — React-компонент, который будет отображаться
при совпадении маршрута.children — вложенные маршруты.loader — асинхронная функция для предварительной
загрузки данных.action — функция для обработки форм и других
действий.Динамическая регистрация заключается в том, чтобы создавать или добавлять такие объекты маршрутов во время работы приложения, а не на этапе статической инициализации.
Простейший пример динамического маршрута:
import { createRouter } from '@tanstack/router';
import { lazy } from 'react';
const router = createRouter({
routeTree: rootRoute, // корневой маршрут
});
function addDynamicRoute(path, component) {
const newRoute = {
path,
component: lazy(component),
};
router.addRoute(newRoute);
}
lazy(component) позволяет загружать компонент по
требованию, что уменьшает начальный вес приложения.router.addRoute динамически добавляет маршрут в текущую
конфигурацию маршрутизатора.Динамическая регистрация особенно полезна для вложенных
маршрутов. Например, если есть модуль dashboard с
несколькими страницами, их можно подключать по мере необходимости:
const dashboardRoute = {
path: '/dashboard',
component: lazy(() => import('./DashboardLayout')),
children: [],
};
router.addRoute(dashboardRoute);
function addDashboardPage(path, component) {
const pageRoute = {
path,
component: lazy(component),
};
dashboardRoute.children.push(pageRoute);
}
Преимущества такого подхода:
TanStack Router поддерживает асинхронное определение маршрутов через промисы или динамические импорты. Это полезно, когда список маршрутов приходит с сервера:
async function loadRoutesFromServer() {
const routesConfig = await fetch('/api/routes').then(res => res.json());
routesConfig.forEach(route => {
router.addRoute({
path: route.path,
component: lazy(() => import(`${route.componentPath}`)),
});
});
}
Особенности:
loader для предварительной
загрузки данных перед рендером компонента.loader и action с динамическими
маршрутамиДинамический маршрут может содержать собственные асинхронные функции для загрузки данных и обработки действий:
router.addRoute({
path: '/users/:id',
component: lazy(() => import('./UserProfile')),
loader: async ({ params }) => {
const response = await fetch(`/api/users/${params.id}`);
return response.json();
},
action: async ({ formData }) => {
await fetch('/api/users/update', {
method: 'POST',
body: formData,
});
},
});
Ключевые моменты:
params автоматически заполняются на основе пути
маршрута.loader выполняется перед рендером компонента, позволяя
получать данные заранее.action позволяет обрабатывать формы и другие события,
связанные с маршрутом.TanStack Router также позволяет управлять маршрутизатором динамически:
router.removeRoute(path) — удаляет маршрут по
пути.router.updateRoute(path, newRouteConfig) — обновляет
существующий маршрут.Это открывает возможность создавать динамические панели управления, где администратор может добавлять или убирать разделы приложения без перезагрузки.
Группировка по модулям Каждая функциональная область приложения должна содержать свой файл маршрутов, чтобы легко добавлять их в корневой маршрут.
Использование lazy для компонентов
Позволяет минимизировать начальный размер бандла и ускорить загрузку
приложения.
Проверка уникальности пути Перед добавлением нового маршрута желательно проверять, что путь ещё не существует, чтобы избежать конфликтов.
Асинхронная конфигурация Хорошей практикой является загрузка маршрутов по необходимости и их регистрация после получения данных с сервера или после проверки прав пользователя.
Динамическая регистрация маршрутов в TanStack Router обеспечивает высокую гибкость, масштабируемость и модульность приложения, делая возможным создание сложных SPA с подгружаемыми и управляемыми во время выполнения маршрутами.