TanStack Router предоставляет мощный механизм для организации маршрутов в приложениях на JavaScript, позволяя строить гибкую навигацию с поддержкой параллельных маршрутов. Параллельные маршруты позволяют рендерить несколько независимых веток интерфейса одновременно, что особенно полезно для сложных приложений с несколькими областями контента, которые должны обновляться независимо друг от друга.
Параллельные маршруты строятся на основе root route, который может содержать несколько дочерних маршрутов, каждый из которых рендерится в своем outlet. Каждый параллельный маршрут управляет своей областью состояния и отображения, не влияя на соседние маршруты. Это позволяет одновременно изменять несколько участков интерфейса без перезагрузки всего приложения.
Ключевые концепции:
Для создания параллельных маршрутов используется структура
route tree, где каждый дочерний маршрут может быть
включен как parallel route branch. В TanStack Router
это делается через children и outletId. Пример
структуры:
import { createRouter, createRouteConfig } from '@tanstack/router';
const routeConfig = createRouteConfig()
.createRoute({
path: '/',
component: RootComponent,
children: [
{
path: 'main',
component: MainComponent,
children: [
{
path: 'sidebar',
component: SidebarComponent,
outletId: 'sidebarOutlet',
},
{
path: 'content',
component: ContentComponent,
outletId: 'contentOutlet',
},
],
},
],
});
const router = createRouter({ routeConfig });
В этом примере sidebar и content являются
параллельными маршрутами. Их рендеринг происходит в разных
outlet, которые нужно определить в
RootComponent и MainComponent:
function MainComponent() {
return (
<div>
<div id="sidebarOutlet" />
<div id="contentOutlet" />
</div>
);
}
TanStack Router позволяет выполнять навигацию как внутри одной ветки,
так и между параллельными маршрутами без перезагрузки остальных
областей. Для этого используется метод router.navigate с
указанием конкретного outletId:
router.navigate({
to: '/main/sidebar',
outletId: 'sidebarOutlet'
});
При этом компонент в contentOutlet остается на месте, и
только SidebarComponent будет обновлен.
Каждый параллельный маршрут может иметь свои loaders и actions для загрузки данных. Важно, что загрузка данных одной ветки не блокирует другие:
const sidebarRoute = routeConfig.createRoute({
path: 'sidebar',
loader: async () => {
const response = await fetch('/api/sidebar');
return response.json();
},
component: SidebarComponent,
outletId: 'sidebarOutlet',
});
Здесь loader выполняется только для
sidebarRoute, что позволяет экономить ресурсы и ускорять
отклик интерфейса.
TanStack Router поддерживает отдельные error boundaries для каждой ветки. Если в одной параллельной ветке возникает ошибка, остальные ветки продолжают работать:
const contentRoute = routeConfig.createRoute({
path: 'content',
component: ContentComponent,
errorComponent: ContentErrorComponent,
outletId: 'contentOutlet',
});
При ошибке загрузки данных или рендеринга в
contentRoute, пользователь увидит только
ContentErrorComponent, а sidebarOutlet
останется полностью функциональным.
Параллельные маршруты повышают модульность, сокращают количество лишних ререндеров и делают приложение более отзывчивым и масштабируемым.