DevGang
Авторизоваться

Как использовать TanStack Router: современная, типобезопасная маршрутизация для React

Для разработчиков React маршрутизация является критически важным аспектом создания приложений. В то время как React Router и Next.js Router доминируют в экосистеме, новый претендент TanStack Router предлагает свежий подход. Разработанный для современной, масштабируемой и типобезопасной навигации, он включает в себя лучшие практики из таких решений, как Remix и Next.js. В этой статье мы рассмотрим основные преимущества и базовую настройку маршрутизации TanStack.

Основные характеристики маршрутизации TanStack

1. Полная безопасность типов

Созданный с учетом TypeScript, TanStack Router обеспечивает полное покрытие типов, минимизируя ошибки времени выполнения. Поддержка IDE выявляет такие проблемы, как неправильные имена параметров или отсутствующие параметры запроса.

2. Встроенные загрузчики данных и кэширование

Благодаря API-интерфейсу, встроенному непосредственно в маршрутизацию:

  • Поддерживает параллельную загрузку данных по маршрутам.
  • Кэширование устаревших данных при повторной проверке прямо из коробки или интеграция с TanStack Query.
  • Предварительно загружает данные при наведении для более быстрой навигации.

3. Расширенное управление параметрами запроса

Маршрутизация TanStack предлагает:

  • Сериализация JSON для сложных объектов.
  • Автоматическая проверка параметров запроса.
  • Промежуточное программное обеспечение для централизованного управления обновлениями запросов.
  • Декларативные и программные инструменты, такие как useSearch и <Link>.

4. Совместимость SSR и интеграция фреймворка

TanStack Router, в первую очередь являясь клиентским маршрутизатором, поддерживает SSR и потоковую передачу. Предстоящие интеграции с фреймворками, такими как TanStack Start, нацелены на конкуренцию с Next.js.

5. Разделение кода и отложенная загрузка

  • Критические и некритические части маршрутов могут быть разделены.
  • Поддерживает маршрутизацию на основе файлов для автоматического создания дерева.

6. Инструменты разработчика

Включает официальные инструменты разработки для визуализации структур маршрутов, состояний кэша и загрузчиков данных.

Сравнение с другими решениями

Маршрутизация TanStack против маршрутизации React

  • Безопасность типов: TanStack Router обеспечивает полную безопасность типов, в отличие от React Router.
  • Кэширование: встроенное кэширование и загрузчики данных превосходят возможности React Router.
  • Параметры запроса: комплексные инструменты для управления запросами.

Маршрутизация TanStack против Next.js

  • Легковесный: идеально подходит для клиентской маршрутизации без накладных расходов, характерных для полноценной среды.
  • Гибкость: более простая интеграция в существующие SPA по сравнению с монолитным подходом Next.js.

Базовая настройка

Маршрутизация на основе кода

import {
  createRouter,
  createRootRoute,
  createRoute,
  RouterProvider,
} from '@tanstack/react-router';

// Define routes
const rootRoute = createRootRoute();
const aboutRoute = createRoute({ getParentRoute: () => rootRoute, path: '/about' });

// Create router instance
const router = createRouter({ routeTree: rootRoute.addChildren([aboutRoute]) });

// Use the router
<RouterProvider router={router} />;

Структурируйте свои маршруты в каталоге /routes и используйте плагин для автоматической генерации дерева маршрутов.

Давайте добавим несколько маршрутов:

import { StrictMode } from 'react';
import ReactDOM from 'react-dom/client';
import {
  createRouter,
  createRootRoute,
  createRoute,
  RouterProvider,
  Outlet,
  Link,
} from '@tanstack/react-router';

import { TanStackRouterDevtools } from '@tanstack/router-devtools';

// Define the root route with a shared layout
const rootRoute = createRootRoute({
  component: () => (
    <>
      <nav>
        <Link to="/">Home</Link>
        <Link to="/about">About</Link>
      </nav>
      <Outlet />
      <TanStackRouterDevtools />
    </>
  ),
});

// Define child routes
const indexRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/',
  component: () => <div>Home Page</div>,
});

const aboutRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/about',
  component: () => <div>About Us</div>,
});

// Build the route tree
const routeTree = rootRoute.addChildren([indexRoute, aboutRoute]);

// Create the router instance
const router = createRouter({ routeTree });

// Register types for TypeScript compatibility
declare module '@tanstack/react-router' {
  interface Register {
    router: typeof router;
  }
}

// Entry point for the application
ReactDOM.createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <RouterProvider router={router} />
  </StrictMode>
);

Эта настройка создает простую маршрутизацию  с двумя маршрутами ("/" и "/about"). Каждый маршрут отображает свой соответствующий компонент при доступе.

Маршрутизация на основе файлов

Для более магического подхода рассмотрите возможность использования маршрутизации на основе файлов. Структура папок внутри /src/routes/... определяет иерархию, а плагин автоматически генерирует дерево маршрутов.

Пример структуры:

src/
 ┣ routes/
 ┃  ┣ __root.tsx   # Root route
 ┃  ┣ index.tsx    # /
 ┃  ┗ about.tsx    # /about
 ┣ main.tsx
 ┗ routeTree.gen.ts (auto-generated)

В __root.tsx, вы можете определить общий макет, верхние и нижние колонтитулы, Devtools и другие глобальные компоненты.

Извлечение данных с помощью загрузчиков

TanStack обеспечивает встроенную поддержку загрузчиков, которые извлекают и кэшируют данные перед рендерингом компонентов.

// src/routes/posts.tsx
import { createFileRoute } from '@tanstack/react-router';
import { fetchPosts } from '@/api';

// Define a route with a loader to fetch posts
export const Route = createFileRoute('/posts')({
  loader: async () => fetchPosts(),
  component: Posts,
});

function Posts() {
  // Access loader data
  const posts = Route.useLoaderData();

  return (
    <ul>
      {posts?.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

При такой настройке переход на /posts вызывает загрузку данных и кэширование перед рендерингом. При повторном посещении в течение срока действия кэша дополнительные запросы на выборку не требуются.

Обработка и проверка параметров поиска

Использование ?searchQuery=... — эффективный способ управления состоянием пользовательского интерфейса, например фильтрами или пагинацией. С TanStack Router вы можете проверять параметры запроса и манипулировать ими без прямой работы с URLSearchParams.

Вот пример маршрута с проверкой и компонентом, который обновляет параметры с помощью useNavigate:

// Define a route with search parameter validation
const ProductsRoute = createFileRoute('/products')({
  validateSearch: (search) => ({ ...search, filter: search.filter ?? '' }),
  component: Products,
});

// Component to read and update query parameters
function Products() {
  const { filter } = ProductsRoute.useSearch();
  const navigate = useNavigate({ from: ProductsRoute.fullPath });

  function setActiveFilter() {
    navigate({ search: (old) => ({ ...old, filter: 'active' }) });
  }

  return (
    <div>
      <p>Current Filter: {filter}</p>
      <button onClick={setActiveFilter}>Active Products</button>
    </div>
  );
}

При таком подходе filter состояние сохраняется в URL-адресе, что упрощает совместное использование, перезагрузку и совместную работу.

Оптимизация рендеринга в TanStack

TanStack Router использует передовые методы оптимизации для минимизации ненужных повторных рендеров. Ключевые механизмы включают:

1. Структурное распределение

При обновлении параметров поиска TanStack Router сохраняет ссылки на неизмененные части. Например, если foo и bar существуют в параметрах поиска и только bar изменяются, ссылка на foo остается прежней, что сокращает повторные рендеры.

2. Мелкозернистые селекторы

Вы можете подписаться на определенные части состояния, используя select опцию в хуках. Это минимизирует повторные рендеры только при изменении выбранного поля.

// Component re-renders only if `foo` changes
const foo = Route.useSearch({ select: ({ foo }) => foo });

3. Структурное распределение с Select

При использовании select возврат нового объекта каждый раз может привести к ненужным повторным рендерам. Включите структурное распределение, чтобы TanStack Router повторно использовал неизмененные объекты.

Включить глобально при создании маршрутизации:

const router = createRouter({
  routeTree,
  defaultStructuralSharing: true,
});

Или включите его локально:

const result = Route.useSearch({
  select: (search) => ({
    foo: search.foo,
    greeting: `Hello, ${search.foo}`,
  }),
  structuralSharing: true,
});

Примечание: данные должны быть совместимы с JSON (например, примитивы, простые объекты, массивы). Несовместимые с JSON данные, такие как new Date() не будут поддерживать структурное совместное использование, и компилятор выдаст предупреждение.

DevTools

Чтобы понять, как маршрутизатор выбирает маршруты, загружает данные или обрабатывает кэширование и ошибки, вы можете использовать TanStack Router Devtools. Эти инструменты отображают текущее дерево маршрутов, состояние кэша, асинхронные загрузки данных и ошибки. Вот пример того, как их настроить:

import { TanStackRouterDevtools } from '@tanstack/router-devtools';

function App() {
  return (
    <>
      <RouterProvider router={router} />
      <TanStackRouterDevtools router={router} />
    </>
  );
}

Панель Devtools можно открывать и закрывать, а ее состояние (открыто/закрыто) сохраняется в localStorage.

Дополнительные возможности

Ниже приведен краткий обзор расширенных возможностей, которые могут быть полезны для определенных сценариев (подробные объяснения доступны в официальной документации TanStack):

1. Виртуальные файловые маршруты

Если обычная маршрутизация на основе файлов не отвечает вашим потребностям, вы можете программно создавать деревья маршрутов. Это позволяет объединять реальные файлы и каталоги под определенными путями.

  • Варианты использования: объединение виртуальных и файловых маршрутов или монтирование стандартных папок маршрутов в пользовательские URL-адреса.

2. Рендеринг на стороне сервера (SSR) и потоковая передача

Маршрутизация TanStack поддерживает как непотоковые, так и потоковые SSR:

  • Непотоковый SSR: загрузка данных, генерация HTML и гидратация полностью отрисованной страницы на клиенте.
  • Потоковая передача SSR: сначала доставляйте критически важный контент для более быстрой отрисовки, параллельно загружая большие объемы данных, что улучшает воспринимаемую скорость.

3. Маскировка маршрута

Маскировка маршрута позволяет отображать один URL-адрес для пользователей, одновременно направляя его на другой путь. Полезно для сокрытия определенных деталей в URL-адресе, таких как модальные параметры или запросы, специфичные для сервиса.

4. Аутентифицированные маршруты

Используйте beforeLoad функцию для проверки аутентификации пользователя. Перенаправляйте неавторизованных пользователей на страницу входа или другой контент. TanStack Router хорошо интегрируется с контекстами React или решениями по управлению состоянием для обработки аутентификации.

5. Мутации данных

Для управления мутациями рассмотрите возможность использования внешних инструментов, таких как TanStack Query или SWR, в сочетании с кэшем маршрутизации. После мутации вызовите router.invalidate(), чтобы легко перепрошить обновленные данные.

6. Восстановление прокрутки

TanStack Router упрощает восстановление прокрутки как для целых страниц, так и для отдельных контейнеров прокрутки. Он устраняет необходимость в специальных решениях для управления позициями прокрутки во время навигации.

Эти функции делают TanStack Router универсальным и мощным инструментом для обработки даже самых сложных сценариев маршрутизации в современных веб-приложениях.

Почему стоит выбрать маршрутизатор TanStack?

TanStack Router идеально подходит для проектов, в которых особое внимание уделяется безопасности типов, оптимизированной выборке данных и управлению запросами. Он дополняет такие инструменты, как TanStack Query, обеспечивая бесперебойный процесс разработки.

TanStack Router воплощает в себе современные практики и обеспечивает непревзойденную гибкость, что кардинально меняет ситуацию в маршрутизации React.

Заключение

TanStack Router предлагает современный, типобезопасный подход к построению надежных систем маршрутизации в приложениях React. Благодаря таким функциям, как загрузчики данных, проверка параметров поиска, поддержка SSR и встроенные механизмы оптимизации, он упрощает разработку динамических масштабируемых приложений. Его бесшовная интеграция с такими инструментами, как React Query, гибкая обработка ошибок и восстановление прокрутки обеспечивает бесперебойную работу разработчика. Независимо от того, создаете ли вы простые SPA или сложные приложения корпоративного уровня, TanStack Router предоставляет инструменты и гибкость, необходимые для эффективного управления маршрутами. Начните изучать его возможности сегодня, чтобы раскрыть весь потенциал ваших проектов React.

Источник:

#React
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу