Хлебные крошки и навигация
Хлебные крошки (breadcrumbs) показывают путь пользователя в иерархии. Помогают ориентироваться и быстро вернуться на уровень выше.
useMatches
React Router v6.4+ предоставляет useMatches — массив совпавших маршрутов:
import { useMatches, Link } from 'react-router-dom';
function Breadcrumbs() {
const matches = useMatches();
return (
<nav>
{matches.map((match, i) => (
<span key={match.pathname}>
{i > 0 && ' / '}
<Link to={match.pathname}>
{(match.handle as { crumb?: string })?.crumb ?? match.pathname}
</Link>
</span>
))}
</nav>
);
}
handle в маршрутах
Маршрут может иметь handle с данными для крошек:
const router = createBrowserRouter([
{
path: '/',
element: <Root />,
handle: { crumb: 'Главная' },
children: [
{
path: 'posts',
element: <Posts />,
handle: { crumb: 'Посты' },
children: [
{
path: ':id',
element: <PostDetail />,
handle: { crumb: 'Пост' },
},
],
},
],
},
]);
useMatches вернёт массив с handle для каждого совпавшего маршрута. Крошки строятся автоматически.
Динамический crumb
Если название зависит от данных — используй функцию:
handle: {
crumb: (data: { title: string }) => data.title,
}
Или передавай через loader.
Хлебные крошки на странице товара
Главная / Каталог / Электроника / Смартфоны / iPhone 15
Каждый уровень — ссылка.
Навигация назад
function BackButton() {
const navigate = useNavigate();
return <button onClick={() => navigate(-1)}>← Назад</button>;
}
Хлебные крошки через props
Если не используешь data router:
function Breadcrumbs({ items }: { items: { label: string; to?: string }[] }) {
return (
<nav>
{items.map((item, i) => (
<span key={i}>
{i > 0 && ' / '}
{item.to ? <Link to={item.to}>{item.label}</Link> : item.label}
</span>
))}
</nav>
);
}
<Breadcrumbs
items={[
{ label: 'Главная', to: '/' },
{ label: 'Посты', to: '/posts' },
{ label: post.title },
]}
/>
Стилизация
Схема:
<nav aria-label="breadcrumb">
<ol className="breadcrumbs">
{items.map((item, i) => (
<li key={i}>
{i < items.length - 1 ? (
<Link to={item.to}>{item.label}</Link>
) : (
<span aria-current="page">{item.label}</span>
)}
</li>
))}
</ol>
</nav>
Доступность
<nav aria-label="breadcrumb"><ol>для порядкаaria-current="page"на последнем элементе- Разделители — CSS
::after, не текст
Итоги
useMatchesдля автоматических крошекhandle.crumbв маршруте- Props для ручных крошек
navigate(-1)для кнопки назад- ARIA для доступности