TanStack Router предоставляет мощный и гибкий механизм маршрутизации для современных приложений на JavaScript и TypeScript. Одной из ключевых возможностей, повышающих производительность и удобство работы с данными маршрутов, является мемоизация данных маршрутов. Этот подход позволяет минимизировать лишние повторные вычисления и загрузку данных при переходах между маршрутами, сохраняя состояние там, где это необходимо.
Мемоизация — это сохранение результатов вычислений для повторного использования. В контексте TanStack Router мемоизация применяется к loader-функциям, которые отвечают за получение данных для маршрута. Если маршрут уже загружался с теми же параметрами, TanStack Router может вернуть ранее сохранённые данные вместо повторного запроса.
Принципы работы мемоизации в маршрутах:
Идентификация маршрута Каждый маршрут имеет уникальный путь и набор параметров. Мемоизация использует комбинацию маршрута и текущих параметров для хранения данных.
Кэширование данных Загруженные данные помещаются в внутренний кэш. При повторном обращении с теми же параметрами кэш проверяется и возвращается результат без повторного вызова loader-функции.
Обновление данных Данные могут быть обновлены
через специальные методы маршрутизатора (invalidate,
refresh) либо при изменении зависимостей, указанных в
конфигурации маршрута.
Для использования мемоизации loader-функции в TanStack Router необходимо:
import { createRouter, createRoute } from '@tanstack/router';
const userRoute = createRoute({
path: '/user/:userId',
loader: async ({ params }) => {
const response = await fetch(`/api/users/${params.userId}`);
return response.json();
},
// Включение мемоизации
memoize: true
});
const router = createRouter({
routes: [userRoute],
});
Ключевые моменты:
memoize: true активирует хранение результатов
loader-функции в кэше.params) и query-параметрам.TanStack Router предоставляет несколько способов управлять кэшированными данными:
router.invalidate('userRoute', { params: { userId: 42 } });
router.refresh('userRoute');
const userRoute = createRoute({
path: '/user/:userId',
loader: async ({ params, context }) => {
const token = context.authToken;
const response = await fetch(`/api/users/${params.userId}`, {
headers: { Authorization: `Bearer ${token}` },
});
return response.json();
},
memoize: true,
deps: ['authToken'], // Кэш сбрасывается при изменении токена
});
Для вложенных маршрутов мемоизация работает на уровне каждого маршрута. Это позволяет:
Пример:
const userRoute = createRoute({ path: '/user/:userId', loader: fetchUser, memoize: true });
const postsRoute = createRoute({ path: 'posts', parent: userRoute, loader: fetchPosts, memoize: true });
const router = createRouter({ routes: [userRoute, postsRoute] });
В этом случае данные пользователя сохраняются при переходе между
вкладками (/user/1/posts, /user/1/settings),
что повышает производительность.
deps, чтобы кэш обновлялся при изменении критичных
значений, например токена аутентификации или фильтров.const productRoute = createRoute({
path: '/products/:productId',
loader: async ({ params }) => {
const response = await fetch(`/api/products/${params.productId}`);
return response.json();
},
memoize: true,
deps: ['userPreferences'],
});
const reviewRoute = createRoute({
path: 'reviews',
parent: productRoute,
loader: async ({ params }) => {
const response = await fetch(`/api/products/${params.productId}/reviews`);
return response.json();
},
memoize: true,
});
const router = createRouter({ routes: [productRoute, reviewRoute] });
// Переход между продуктами с сохранением кэша для уже посещённых
router.navigate('/products/123/reviews');
router.navigate('/products/123'); // Данные продукта берутся из кэша
router.navigate('/products/124'); // Кэш сбрасывается для нового productId
Использование мемоизации в TanStack Router значительно повышает отзывчивость приложения и снижает нагрузку на сервер, сохраняя данные маршрутов там, где это оправдано по логике работы.