TanStack Router предоставляет мощную систему маршрутизации,
ориентированную на React и другие фреймворки, с упором на реактивное
состояние и декларативное управление маршрутами. Важной частью этой
системы является возможность создания пользовательских
хуков, основанных на встроенных хуках маршрутизатора, таких как
useRouter, useRoute, useParams и
useMatches. Эти хуки позволяют инкапсулировать
повторяющуюся логику, повышать читаемость кода и облегчать повторное
использование функций.
Основная идея пользовательского хука заключается в том, чтобы обернуть встроенный хук и добавить к нему дополнительную логику. Рассмотрим пример на базе маршрутизатора TanStack Router:
import { useRoute, useParams } from '@tanstack/router';
function useUserData() {
const route = useRoute();
const params = useParams();
const userId = params.userId;
// Дополнительная логика, например, выборка данных из API или локального состояния
const [user, setUser] = React.useState(null);
React.useEffect(() => {
if (userId) {
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(data => setUser(data));
}
}, [userId]);
return { user, route, userId };
}
Здесь пользовательский хук useUserData использует
встроенные useRoute и useParams, добавляя
асинхронную логику загрузки данных пользователя. Такой подход позволяет
использовать хук в разных компонентах без дублирования кода.
Инкапсуляция логики Вся работа с маршрутными параметрами и асинхронными операциями скрыта внутри одного хука, что делает компонент более чистым.
Повторное использование Один хук можно использовать в разных местах приложения, минимизируя вероятность ошибок.
Поддержка типизации TanStack Router поддерживает TypeScript, поэтому пользовательские хуки можно типизировать для строгого контроля параметров:
import { useParams } from '@tanstack/router';
interface UserParams {
userId: string;
}
function useTypedUserParams() {
const params = useParams();
return params;
}
Помимо обертки для добавления логики, можно создавать хуки для работы с несколькими маршрутами одновременно:
import { useMatches } from '@tanstack/router';
function useCurrentUserAndSettings() {
const matches = useMatches();
const userMatch = matches.find(m => m.route.id === 'userRoute');
const settingsMatch = matches.find(m => m.route.id === 'settingsRoute');
const user = userMatch?.data.user;
const settings = settingsMatch?.data.settings;
return { user, settings };
}
Такой хук объединяет данные из разных маршрутов, что особенно полезно для глобальных компонентов, например, навигационных панелей или хедеров.
TanStack Router позволяет интегрировать пользовательские хуки с
загрузкой данных через loader маршрута. Пользовательский
хук может получать предзагруженные данные и обновлять их при изменении
параметров:
import { useRouteLoaderData } from '@tanstack/router';
function usePostData(postId) {
const data = useRouteLoaderData({ routeId: 'postRoute', params: { postId } });
// Дополнительная обработка данных
const post = data ? { ...data, title: data.title.toUpperCase() } : null;
return post;
}
Такой подход уменьшает количество сетевых запросов и повышает производительность приложения.
Пользовательские хуки удобно комбинировать с глобальными состояниями,
например, через React Context или Zustand. Это позволяет
синхронизировать данные маршрутов с состоянием приложения:
import { useParams } from '@tanstack/router';
import { useUserStore } from '../stores/userStore';
function useSyncUser() {
const { userId } = useParams();
const { setUser } = useUserStore();
React.useEffect(() => {
if (userId) {
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(setUser);
}
}, [userId, setUser]);
}
Такой хук автоматически обновляет глобальное состояние при изменении маршрута, обеспечивая консистентность данных.
useEffect.