Динамическая регистрация маршрутов

В 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) — обновляет существующий маршрут.

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


Советы по организации динамических маршрутов

  1. Группировка по модулям Каждая функциональная область приложения должна содержать свой файл маршрутов, чтобы легко добавлять их в корневой маршрут.

  2. Использование lazy для компонентов Позволяет минимизировать начальный размер бандла и ускорить загрузку приложения.

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

  4. Асинхронная конфигурация Хорошей практикой является загрузка маршрутов по необходимости и их регистрация после получения данных с сервера или после проверки прав пользователя.


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