Как реализовать мультислешевые параметры в 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-параметры. Это сохранит функциональность и обеспечит корректную работу с вложенными путями.