Как реализовать мультислешевые параметры в react-router-dom 6.29.0

    При миграции проекта на React 18 и react-router-dom 6.29.0 многие разработчики сталкиваются с проблемой: старый синтаксис /guide/:categories*/article/:articleId перестаёт работать корректно. Вместо ожидаемой строки 28/29/38/39/40 параметр categories получает только первое значение - 28. Это связано с изменениями в механизме разбора маршрутов в шестой версии библиотеки. Рассмотрим, как правильно обрабатывать мультислешевые параметры (splat-параметры) в react-router-dom v6.

    Почему старый синтаксис не работает в v6

    В react-router-dom v5 символ * после имени параметра (:categories*) означал, что параметр может содержать несколько сегментов пути, разделённых слешами. В v6 семантика звёздочки изменилась: теперь * используется только в конце маршрута для обозначения сплат-параметра, который захватывает весь оставшийся путь. Если поставить * внутри маршрута, как в /guide/:categories*/article/:articleId, роутер интерпретирует это неверно - он останавливается на первом слеше после :categories и не передаёт вложенные сегменты.

    Решение: использование сплат-параметра в конце маршрута

    Единственный надёжный способ в react-router-dom 6.29.0 - перенести мультислешевый параметр в конец пути и использовать splat (*). Например, перепишите маршрут как /guide/*/article/:articleId. Тогда в компоненте вы сможете получить весь вложенный путь через хук useParams() и свойство '*'. Однако этот подход требует дополнительной обработки: вам нужно будет вручную извлечь нужные сегменты из строки.

    Пример реализации

    // Определение маршрута
    <Route path='/guide/*/article/:articleId' element={<GuidePage />} />
    
    // В компоненте GuidePage
    import { useParams } from 'react-router-dom';
    
    function GuidePage() {
      const { '*': splat, articleId } = useParams();
      // splat = '28/29/38/39/40'
      const categories = splat ? splat.split('/') : [];
      // categories = ['28', '29', '38', '39', '40']
      // ...
    }

    Как видите, splat возвращает всё, что находится между /guide/ и /article/. Затем вы можете разбить эту строку на массив и использовать по необходимости.

    Альтернативный подход: query-параметры

    Если структура URL не критична, рассмотрите возможность передачи вложенных идентификаторов через query-параметры. Например: /guide/article/103?categories=28,29,38,39,40. Это полностью совместимо с react-router-dom v6 и не требует сложных маршрутов. Параметры читаются через хук useSearchParams().

    Дополнительные рекомендации

    • Избегайте использования * в середине пути - это не поддерживается в react-router-dom v6.
    • Если вам нужно строгое соответствие старому поведению, используйте сплат-параметр в конце маршрута и обрабатывайте его вручную.
    • Проверьте версию библиотеки: в 6.29.0 синтаксис стабилен, но следите за обновлениями документации.

    Таким образом, для реализации мультислешевых параметров в react-router-dom 6.29.0 используйте сплат (*) в конце маршрута или переходите на query-параметры. Это сохранит функциональность и обеспечит корректную работу с вложенными путями.

    Часто задаваемые вопросы