Активные ссылки

В MUI (Material-UI) управление навигацией и активными ссылками строится на сочетании компонентов Link, Button и систем маршрутизации, таких как react-router-dom. Ключевая задача — визуально выделять текущий маршрут и корректно обрабатывать навигацию без перезагрузки страницы.


MUI предоставляет компонент Link, который может быть использован как для внешних, так и для внутренних ссылок. Для работы с внутренними маршрутами часто используют component={RouterLink}:

import { Link } from '@mui/material';
import { Link as RouterLink, useLocation } from 'react-router-dom';

const NavigationLink = ({ to, children }) => {
  const location = useLocation();
  const isActive = location.pathname === to;

  return (
    <Link
      component={RouterLink}
      to={to}
      underline="none"
      color={isActive ? 'primary' : 'textPrimary'}
      sx={{
        fontWeight: isActive ? 'bold' : 'normal',
        borderBottom: isActive ? '2px solid' : 'none',
        paddingBottom: '2px'
      }}
    >
      {children}
    </Link>
  );
};

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

  • Использование useLocation позволяет определить текущий путь.
  • Свойство component={RouterLink} интегрирует MUI Link с роутером.
  • sx применяется для динамического стилизования активного состояния.

Использование Button как ссылки

Иногда ссылки оформляют в виде кнопок для навигации. В MUI компонент Button может работать как ссылка через component:

import { Button } from '@mui/material';
import { Link as RouterLink, useLocation } from 'react-router-dom';

const NavButton = ({ to, children }) => {
  const location = useLocation();
  const isActive = location.pathname === to;

  return (
    <Button
      component={RouterLink}
      to={to}
      variant={isActive ? 'contained' : 'text'}
      color={isActive ? 'primary' : 'inherit'}
    >
      {children}
    </Button>
  );
};

Особенности подхода:

  • variant="contained" выделяет активную кнопку.
  • Состояние isActive управляет цветом и стилем кнопки.
  • Такой подход удобен для навигационных панелей и меню.

Динамическая навигация с Tabs

Для горизонтальных меню или табов MUI предоставляет компонент Tabs и Tab. С помощью value можно управлять активной вкладкой:

import { Tabs, Tab } from '@mui/material';
import { useLocation, useNavigate } from 'react-router-dom';

const NavigationTabs = () => {
  const location = useLocation();
  const navigate = useNavigate();

  const tabConfig = [
    { label: 'Главная', path: '/' },
    { label: 'О нас', path: '/about' },
    { label: 'Контакты', path: '/contact' }
  ];

  const currentTab = tabConfig.findIndex(tab => tab.path === location.pathname);

  return (
    <Tabs
      value={currentTab !== -1 ? currentTab : false}
      onCha nge={(event, newValue) => navigate(tabConfig[newValue].path)}
    >
      {tabConfig.map((tab, index) => (
        <Tab key={index} label={tab.label} />
      ))}
    </Tabs>
  );
};

Основные моменты:

  • value определяет индекс активного таба.
  • onChange использует navigate для изменения маршрута без перезагрузки.
  • Такой подход упрощает синхронизацию маршрута и активного состояния визуальных элементов.

Стилизация активной ссылки через sx и темы

MUI позволяет использовать тему для унифицированного оформления активных элементов. Пример с динамической цветовой схемой:

<Link
  component={RouterLink}
  to="/profile"
  sx={(theme) => ({
    color: location.pathname === '/profile' ? theme.palette.primary.main : theme.palette.text.primary,
    fontWeight: location.pathname === '/profile' ? 'bold' : 'normal',
    '&:hover': {
      textDecoration: 'underline',
    },
  })}
>
  Профиль
</Link>

Выводы по стилизации:

  • Использование sx с функцией темы обеспечивает доступ к цветам и типографике.
  • Псевдоклассы (&:hover) добавляют интерактивность.
  • Совмещение isActive и темы позволяет централизованно управлять стилем активной ссылки.

Поддержка вложенных маршрутов

При работе с вложенными путями можно использовать startsWith вместо строгого сравнения:

const isActive = location.pathname.startsWith('/dashboard');

Это полезно для выделения главного меню при переходе по внутренним страницам:

  • /dashboard
  • /dashboard/settings
  • /dashboard/profile

Все эти пути будут считаться активными для одного родительского элемента.


Анимация и переходы

MUI интегрируется с framer-motion или CSS-переходами для плавного изменения стилей активной ссылки:

<Link
  component={RouterLink}
  to="/services"
  sx={{
    position: 'relative',
    '&::after': {
      content: '""',
      position: 'absolute',
      width: location.pathname === '/services' ? '100%' : '0%',
      height: '2px',
      backgroundColor: 'primary.main',
      bottom: 0,
      left: 0,
      transition: 'width 0.3s ease-in-out',
    },
  }}
>
  Услуги
</Link>

Примечания:

  • Псевдоэлемент ::after создает анимацию подчеркивания.
  • transition обеспечивает плавный эффект.
  • Такой подход делает интерфейс более живым и визуально понятным.

Выводы по работе с активными ссылками

MUI предоставляет гибкие возможности:

  • Link и Button интегрируются с маршрутизаторами.
  • Tabs удобны для горизонтального меню.
  • Состояние активности управляется через useLocation и логические проверки.
  • sx и тема обеспечивают централизованное и динамическое оформление.
  • Поддержка вложенных маршрутов и анимаций делает навигацию удобной и интерактивной.