Вложенные маршруты и их иерархия

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

Каждый маршрут определяется с помощью объекта конфигурации, который содержит ключевые свойства:

  • path — путь маршрута.
  • component — React-компонент, который рендерится при совпадении пути.
  • children — массив дочерних маршрутов, создающий иерархию.

Пример базовой структуры:

import { createRouter, Route } from '@tanstack/router';
import HomePage from './pages/HomePage';
import DashboardPage from './pages/DashboardPage';
import SettingsPage from './pages/SettingsPage';
import ProfilePage from './pages/ProfilePage';

const router = createRouter({
  routeConfig: [
    {
      path: '/',
      component: HomePage,
      children: [
        {
          path: 'dashboard',
          component: DashboardPage,
          children: [
            { path: 'settings', component: SettingsPage },
            { path: 'profile', component: ProfilePage },
          ],
        },
      ],
    },
  ],
});

В данном примере SettingsPage и ProfilePage являются дочерними маршрутами DashboardPage, а DashboardPage — дочерним маршрутом корня /.


Иерархия и вложенность

Ключевой принцип: каждый дочерний маршрут наследует контекст родителя. Это означает, что данные, загруженные на уровне родителя, доступны на всех уровнях вложенности, что особенно удобно для layout-компонентов и общих состояний страницы.

Пример layout-компонента с вложенными маршрутами:

function DashboardLayout({ children }) {
  return (
    
  );
}

const dashboardRoute = {
  path: 'dashboard',
  component: DashboardLayout,
  children: [
    { path: 'settings', component: SettingsPage },
    { path: 'profile', component: ProfilePage },
  ],
};

DashboardLayout рендерит навигацию и область main, куда подставляются дочерние маршруты. Это позволяет избежать дублирования UI и сосредоточить общий интерфейс на уровне родителя.


Параметры и динамические сегменты

Вложенные маршруты поддерживают динамические параметры, которые передаются через путь. Это делает возможной организацию страниц, основанных на ID ресурсов или других переменных.

Пример:

const userRoute = {
  path: 'users/:userId',
  component: UserLayout,
  children: [
    { path: 'profile', component: UserProfilePage },
    { path: 'settings', component: UserSettingsPage },
  ],
};

В этом случае :userId доступен как параметр родителя и может быть использован всеми дочерними маршрутами. Для получения параметров используется хук useParams():

import { useParams } from '@tanstack/router';

function UserProfilePage() {
  const { userId } = useParams();
  return 
Профиль пользователя {userId}
; }

Стратегии рендеринга вложенных маршрутов

TanStack Router поддерживает два основных подхода для рендеринга:

  1. Полная замена контента — дочерний маршрут полностью рендерится внутри родительского component.
  2. Составной рендеринг через Outlet — специальный компонент Outlet используется в родительском компоненте, чтобы рендерить дочерние маршруты.

Пример с Outlet:

import { Outlet } from '@tanstack/router';

function DashboardLayout() {
  return (
    
  );
}

Outlet автоматически подставляет компонент текущего активного дочернего маршрута, что делает иерархию гибкой и удобной для масштабирования.


Глубокие вложенные маршруты

Вложенность может быть произвольной глубины. Важно следить за:

  • Читаемостью конфигурации — глубокие уровни стоит структурировать через отдельные модули.
  • Управлением состоянием — часто родительский маршрут становится “контейнером данных” для всех потомков.

Пример:

const router = createRouter({
  routeConfig: [
    {
      path: '/',
      component: AppLayout,
      children: [
        {
          path: 'projects',
          component: ProjectsLayout,
          children: [
            {
              path: ':projectId',
              component: ProjectDetailLayout,
              children: [
                { path: 'tasks', component: ProjectTasksPage },
                { path: 'team', component: ProjectTeamPage },
              ],
            },
          ],
        },
      ],
    },
  ],
});

Здесь каждая вложенность создаёт отдельный уровень UI и данных: AppLayoutProjectsLayoutProjectDetailLayout → страницы задач и команды.


Важные рекомендации по вложенной архитектуре

  • Использовать layout-компоненты на уровнях родителя, чтобы минимизировать дублирование.
  • Сохранять смысловую иерархию: маршруты должны отражать логику приложения.
  • Передавать параметры через родителя и использовать их в потомках, избегая глобального состояния.
  • Разделять конфигурацию на модули, если дерево маршрутов слишком большое, чтобы улучшить читаемость и поддержку.

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