Splat routes для сложных паттернов

Splat routes в React Router — это механизм, позволяющий создавать маршруты с динамическими или «захватывающими» сегментами URL. В отличие от стандартных параметров пути (:param), которые соответствуют только одному сегменту, splat (*) позволяет «поймать» несколько сегментов сразу, что особенно полезно для вложенных маршрутов и маршрутов с произвольной глубиной.

Основы использования * в пути

Синтаксис splat-route выглядит следующим образом:

<Route path="/files/*" element={<Files />} />

Здесь * в конце пути означает, что компонент Files будет рендериться для всех URL, начинающихся с /files/, включая вложенные пути:

  • /files/documents
  • /files/images/icons
  • /files/documents/2026/reports

При этом все «захваченные» сегменты становятся доступными через хук useParams:

import { useParams } from 'react-router-dom';

function Files() {
  const params = useParams();
  console.log(params['*']); // 'documents/2026/reports'
  return <div>Путь: {params['*']}</div>;
}

Ключевой момент: splat захватывает всё, что остаётся после базового пути, включая слеши.

Комбинирование с обычными параметрами

Splat routes можно комбинировать с обычными параметрами:

<Route path="/users/:userId/*" element={<UserProfile />} />
  • /users/42/settings/privacy
  • /users/42/posts/2026/march

В компоненте UserProfile доступны оба значения:

const { userId, '*' : rest } = useParams();
console.log(userId); // '42'
console.log(rest);   // 'settings/privacy' или 'posts/2026/march'

Это позволяет строить универсальные маршруты для страниц с вложенной навигацией.

Использование splat для построения вложенных маршрутов

Splat идеально подходит для динамических вложенных маршрутов без необходимости заранее определять все уровни:

<Route path="/dashboard/*" element={<Dashboard />}>
  <Route path="analytics/*" element={<Analytics />} />
  <Route path="reports/*" element={<Reports />} />
</Route>

В этом примере любой путь, начинающийся с /dashboard, будет сначала обрабатываться компонентом Dashboard, а затем можно использовать вложенные splat для дальнейшей маршрутизации внутри него.

Lazy routing и code-splitting

Splat позволяет эффективно внедрять ленивую загрузку (lazy loading) компонентов для больших приложений:

const Reports = React.lazy(() => import('./Reports'));

<Route path="/dashboard/reports/*" element={
  <React.Suspense fallback={<div>Загрузка...</div>}>
    <Reports />
  </React.Suspense>
} />

Все вложенные пути /dashboard/reports/* будут загружать компонент Reports только при необходимости, что уменьшает размер основного бандла.

Redirects и навигация внутри splat

При использовании useNavigate можно перенаправлять пользователей внутри splat-пути:

import { useNavigate } from 'react-router-dom';

function Files() {
  const navigate = useNavigate();
  
  function goToSubfolder(subfolder) {
    navigate(subfolder);
  }

  return (
    <button onCl ick={() => goToSubfolder('documents/2026')}>Документы 2026</button>
  );
}

navigate работает относительно текущего маршрута, что делает его удобным для вложенных и динамических маршрутов.

Ограничения и особенности

  • Порядок маршрутов важен: более специфичные пути должны быть выше в списке <Routes>. Иначе splat может «захватить» слишком много URL и блокировать другие маршруты.
  • Захват слешей: splat включает все слеши, поэтому часто необходимо дополнительное разбиение строки при работе с вложенной логикой.
  • Комбинация с index route: внутри splat можно определять index-маршрут для обработки базового пути без дополнительных сегментов.

Примеры практического применения

  1. Файловые менеджеры: /files/* позволяет отобразить любую глубину вложенных папок.
  2. Дашборды и админ-панели: /admin/* с динамической подгрузкой компонентов для каждой секции.
  3. Документация и блоги: /docs/* позволяет рендерить статьи с многоуровневой иерархией URL.

Splat routes значительно упрощают работу с динамическими и многоуровневыми маршрутами, позволяя создавать гибкую архитектуру приложений без необходимости вручную прописывать все варианты URL.