В TanStack Router контекст используется для управления данными, которые должны быть доступны на уровне маршрута и вложенных компонентов. Контексты позволяют передавать состояние и функции без необходимости пробрасывать их через props, что особенно важно для крупных приложений с глубокими вложенными маршрутами.
Контекст маршрута в TanStack Router создаётся через
createRouteContext и привязывается к конкретному маршруту.
Это позволяет каждому маршруту иметь собственный набор данных, доступный
всем дочерним компонентам. Контекст работает подобно React Context, но
оптимизирован для маршрутизации и асинхронного получения данных.
Пример создания контекста для маршрута:
import { createRouteContext } from '@tanstack/router';
const UserContext = createRouteContext({
// тип данных, хранимых в контексте
defaultValue: {
user: null,
setUser: () => {}
}
});
Здесь defaultValue определяет начальное состояние
контекста. Контекст можно расширять и изменять, добавляя методы для
обновления состояния.
Контекст привязывается к маршруту с помощью свойства
context. Это обеспечивает доступ к контексту в компоненте
маршрута и всех его вложенных маршрутах:
import { Route } from '@tanstack/router';
const userRoute = new Route({
path: '/user',
component: UserComponent,
context: UserContext
});
После привязки контекста компонент UserComponent может
получать и изменять данные контекста через хук useContext
маршрута.
Для работы с контекстом внутри компонента маршрута используется хук
useRouteContext. Он обеспечивает типизированный и
безопасный доступ к данным и методам контекста:
import { useRouteContext } from '@tanstack/router';
function UserComponent() {
const { user, setUser } = useRouteContext(UserContext);
return (
<div>
<h1>{user?.name || 'Гость'}</h1>
<button onCl ick={() => setUser({ name: 'Иван' })}>Войти как Иван</button>
</div>
);
}
Хук автоматически подписывает компонент на изменения контекста. При обновлении состояния компонента, использующие контекст, будут перерендерены только при изменении значимых данных, что оптимизирует производительность.
TanStack Router поддерживает иерархию контекстов. Вложенный маршрут может наследовать контекст родительского маршрута или использовать свой собственный. Если контекст не указан, дочерний маршрут получает доступ только к контексту родителя:
const profileRoute = new Route({
path: '/profile',
component: ProfileComponent,
parent: userRoute // наследует UserContext
});
function ProfileComponent() {
const { user } = useRouteContext(UserContext);
return <p>Профиль пользователя: {user?.name}</p>;
}
Наследование контекста упрощает управление состоянием на уровне группы маршрутов, избегая дублирования данных и функций.
Контексты могут создаваться динамически при необходимости асинхронной загрузки данных:
const PostContext = createRouteContext({
defaultValue: { post: null },
async load({ params }) {
const response = await fetch(`/api/posts/${params.id}`);
const post = await response.json();
return { post };
}
});
Метод load вызывается при переходе на маршрут и
позволяет заранее загружать данные для контекста, делая компонент
маршрута готовым к отображению сразу после монтирования.
load позволяет
интегрировать TanStack Router с API без необходимости отдельного
состояния в компонентах.Контексты в TanStack Router — это мощный инструмент для построения структурированных и поддерживаемых маршрутов с локальным и глобальным состоянием, позволяющий управлять данными на уровне маршрутов без необходимости глобального состояния или сложного пробрасывания props.