Условные layouts — это механизм, позволяющий динамически изменять структуру приложения в зависимости от состояния маршрута или данных, связанных с ним. TanStack Router предоставляет гибкие инструменты для построения таких layouts, сохраняя при этом высокую производительность и предсказуемость маршрутизации.
В TanStack Router layout представляет собой компонент, который оборачивает дочерние маршруты, предоставляя общую структуру интерфейса: навигацию, боковые панели, футеры, модальные окна. Условные layouts позволяют:
Ключевой элемент — использование функции children внутри
route для динамического определения, какой layout должен
применяться.
Рассмотрим пример, когда приложение имеет два основных типа страниц: публичные и защищённые.
import { createRouter, RouterProvider } from '@tanstack/router';
import PublicLayout from './layouts/PublicLayout';
import ProtectedLayout from './layouts/ProtectedLayout';
import HomePage from './pages/HomePage';
import DashboardPage from './pages/DashboardPage';
import LoginPage from './pages/LoginPage';
import { useAuth } from './auth';
const router = createRouter({
routeTree: [
{
path: '/',
element: ,
children: [
{
path: '/',
element: ({ params }) => {
const { isAuthenticated } = useAuth();
return isAuthenticated ? : ;
},
children: [
{ path: '/', element: },
{ path: '/dashboard', element: },
{ path: '/login', element: },
],
},
],
},
],
});
В этом примере компонент layout выбирается
динамически на основе состояния
isAuthenticated. Если пользователь авторизован,
оборачивается ProtectedLayout, иначе —
PublicLayout.
loader для выбора layoutTanStack Router позволяет применять загрузчики данных
(loader) для предварительной подготовки данных
перед рендером маршрута. Это удобно для условных layouts, когда
необходимо проверять роли пользователя или права доступа.
const dashboardRoute = {
path: '/dashboard',
loader: async ({ context }) => {
const user = await context.getCurrentUser();
if (!user) {
throw redirect('/login');
}
return user;
},
element: ,
};
Здесь loader выполняет проверку и перенаправляет
неавторизованных пользователей. Это позволяет разделять логику layout и
сам контент страницы.
TanStack Router поддерживает вложенные маршруты, что позволяет комбинировать несколько условных layouts. Например, внутри защищённого layout можно добавить layout для панели администратора:
const adminRoute = {
path: '/admin',
element: ({ user }) => user.role === 'admin' ? : ,
children: [
{ path: '/admin/users', element: },
{ path: '/admin/settings', element: },
],
};
Такой подход обеспечивает:
loader и context для
передачи состояния, чтобы layout оставался презентационным
компонентом.Условные layouts в TanStack Router не перегружают
рендер, если корректно использовать ключи маршрутов и
React.memo для компонентов layouts. Вложенные layouts
рендерятся только при изменении соответствующей части маршрута, что
снижает количество лишних обновлений DOM.
const routes = [
{
path: '/',
element: ,
children: [
{
path: '/',
element: ({ user }) => user ? : ,
children: [
{ path: '/', element: },
{ path: '/login', element: },
{ path: '/dashboard', element: },
],
},
{
path: '/admin',
element: ({ user }) => user?.role === 'admin' ? : ,
children: [
{ path: '/admin/users', element: },
{ path: '/admin/settings', element: },
],
},
],
},
];
Эта структура демонстрирует чистое разделение логики и контента, позволяя легко расширять приложение новыми conditional layouts без изменения существующих компонентов.