Breadcrumbs с роутингом

Breadcrumbs в библиотеке MUI (Material-UI) используются для отображения навигационной цепочки, позволяя пользователю видеть текущее положение в структуре приложения и быстро переходить к предыдущим уровням. В сочетании с роутингом они становятся мощным инструментом для улучшения UX в сложных SPA (Single Page Application) на React.


Импорт и базовая структура

Для начала необходимо импортировать компонент Breadcrumbs и вспомогательные элементы:

import React from 'react';
import { Breadcrumbs, Link, Typography } from '@mui/material';
import { Link as RouterLink, useLocation } from 'react-router-dom';
  • Breadcrumbs — контейнер для элементов навигации.
  • Link — визуальный компонент ссылки из MUI.
  • RouterLink — компонент из react-router-dom, обеспечивающий навигацию без перезагрузки страницы.
  • useLocation — хук для получения текущего URL.

Простейший пример с роутингом

function SimpleBreadcrumbs() {
  return (
    <Breadcrumbs aria-label="breadcrumb">
      <Link component={RouterLink} to="/">
        Главная
      </Link>
      <Link component={RouterLink} to="/catalog">
        Каталог
      </Link>
      <Typography color="text.primary">Товар</Typography>
    </Breadcrumbs>
  );
}

Ключевые моменты:

  • Последний элемент отображается с использованием Typography, чтобы показать текущую страницу и сделать его некликабельным.
  • Все предыдущие уровни используют Link с component={RouterLink} для интеграции с роутером.

Динамическое формирование хлебных крошек

В реальных приложениях URL может быть динамическим, например /catalog/electronics/laptop. Для генерации крошек на основе текущего пути удобно использовать useLocation:

function DynamicBreadcrumbs() {
  const location = useLocation();
  const pathnames = location.pathname.split('/').filter((x) => x);

  return (
    <Breadcrumbs aria-label="breadcrumb">
      <Link component={RouterLink} to="/">
        Главная
      </Link>
      {pathnames.map((value, index) => {
        const to = `/${pathnames.slice(0, index + 1).join('/')}`;
        const isLast = index === pathnames.length - 1;
        return isLast ? (
          <Typography key={to} color="text.primary">
            {decodeURIComponent(value)}
          </Typography>
        ) : (
          <Link key={to} component={RouterLink} to={to}>
            {decodeURIComponent(value)}
          </Link>
        );
      })}
    </Breadcrumbs>
  );
}

Пояснения:

  • split('/') разделяет путь на сегменты.
  • filter(x => x) исключает пустые строки, чтобы избежать лишних крошек.
  • slice формирует корректный путь для каждой промежуточной крошки.
  • decodeURIComponent позволяет корректно отображать сегменты с пробелами или кириллицей.

Настройка внешнего вида

MUI позволяет кастомизировать внешний вид крошек:

<Breadcrumbs
  separator="›"
  sx={{
    '& .MuiBreadcrumbs-separator': {
      color: 'grey.500',
      fontSize: '1.2rem',
    },
    '& a': {
      textDecoration: 'none',
      color: 'primary.main',
      '&:hover': {
        textDecoration: 'underline',
      },
    },
  }}
>
  {/* Элементы крошек */}
</Breadcrumbs>

Особенности:

  • separator задаёт символ между крошками. По умолчанию это «/».
  • sx позволяет применять кастомные стили без внешних CSS-файлов.

Для улучшения визуального восприятия можно добавлять иконки к каждой крошке:

import HomeIcon from '@mui/icons-material/Home';
import CategoryIcon from '@mui/icons-material/Category';

<Breadcrumbs aria-label="breadcrumb">
  <Link component={RouterLink} to="/" sx={{ display: 'flex', alignItems: 'center' }}>
    <HomeIcon sx={{ mr: 0.5 }} fontSize="inherit" />
    Главная
  </Link>
  <Link component={RouterLink} to="/catalog" sx={{ display: 'flex', alignItems: 'center' }}>
    <CategoryIcon sx={{ mr: 0.5 }} fontSize="inherit" />
    Каталог
  </Link>
  <Typography color="text.primary">Товар</Typography>
</Breadcrumbs>
  • Использование sx={{ mr: 0.5 }} добавляет отступ между иконкой и текстом.
  • display: 'flex' и alignItems: 'center' выравнивают текст и иконку по горизонтали.

Оптимизация производительности

При динамическом формировании хлебных крошек важно учитывать:

  • useMemo для мемоизации массива pathnames, если рендер выполняется часто.
  • Ленивая загрузка иконок и тяжелых компонентов для ускорения рендеринга.
const pathnames = React.useMemo(() => location.pathname.split('/').filter(Boolean), [location.pathname]);

Обработка сложных URL

Иногда сегменты пути не совпадают с названиями для отображения:

const breadcrumbNameMap = {
  catalog: 'Каталог',
  electronics: 'Электроника',
  laptop: 'Ноутбуки',
};

{pathnames.map((value, index) => {
  const to = `/${pathnames.slice(0, index + 1).join('/')}`;
  const isLast = index === pathnames.length - 1;
  const name = breadcrumbNameMap[value] || value;
  return isLast ? (
    <Typography key={to} color="text.primary">
      {name}
    </Typography>
  ) : (
    <Link key={to} component={RouterLink} to={to}>
      {name}
    </Link>
  );
})}
  • breadcrumbNameMap позволяет отображать человекочитаемые имена вместо системных сегментов URL.
  • Позволяет легко добавлять мультиязычность и кастомизацию.

Интеграция с Material UI Theme

Breadcrumbs легко интегрируются с темой MUI:

<Breadcrumbs
  separator="›"
  sx={(theme) => ({
    '& a': {
      color: theme.palette.primary.main,
    },
    '& .MuiBreadcrumbs-separator': {
      color: theme.palette.text.secondary,
    },
  })}
>
  {/* элементы */}
</Breadcrumbs>
  • Использование функции sx с theme позволяет использовать цвета и отступы из глобальной темы приложения.
  • Обеспечивает единый стиль интерфейса без дублирования CSS.

Breadcrumbs в MUI с роутингом — это гибкий инструмент, который при правильной настройке обеспечивает интуитивную навигацию, улучшает UX и позволяет динамически управлять навигационными путями в приложении на React. Их сочетание с react-router-dom, кастомными стилями и иконками позволяет создавать как простые цепочки навигации, так и сложные многоуровневые структуры.