В React Router управление навигацией осуществляется через компоненты
<Link> и <NavLink>. Основное
отличие между ними заключается в возможности
<NavLink> автоматически определять, какая ссылка
активна в текущий момент, и применять специальные стили или классы для
активного состояния.
<NavLink>Компонент <NavLink> расширяет функциональность
<Link> добавлением пропсов
activeClassName и activeStyle (в версии React
Router 6 и выше используется функция className или
style, зависящая от состояния). Это позволяет динамически
изменять внешний вид ссылок в зависимости от текущего маршрута.
Пример использования в React Router v6:
import { NavLink } from 'react-router-dom';
function Navigation() {
return (
<nav>
<NavLink
to="/"
className={({ isActive }) => isActive ? 'active-link' : 'inactive-link'}
>
Главная
</NavLink>
<NavLink
to="/about"
className={({ isActive }) => isActive ? 'active-link' : 'inactive-link'}
>
О нас
</NavLink>
</nav>
);
}
Здесь ключевой момент — использование функции для
className, принимающей объект с полем
isActive. Когда маршрут совпадает с to,
isActive становится true, и ссылка получает
указанный класс.
styleПомимо классов, можно применять инлайн-стили:
<NavLink
to="/contact"
style={({ isActive }) => ({
color: isActive ? 'white' : 'gray',
backgroundColor: isActive ? 'blue' : 'transparent',
padding: '8px 12px',
borderRadius: '4px',
textDecoration: 'none'
})}
>
Контакты
</NavLink>
Такой подход позволяет полностью контролировать визуальное представление активной ссылки без необходимости писать отдельные CSS-классы.
Когда маршруты вложенные, React Router по умолчанию считает ссылку
активной только при точном совпадении. Для включения активации при
частичном совпадении используется проп end:
<NavLink
to="/products"
end
className={({ isActive }) => isActive ? 'active-link' : ''}
>
Продукты
</NavLink>
Без end ссылка /products будет активна
также для /products/123 или /products/new.
Добавление end заставляет компонент быть активным только
при точном совпадении пути.
При сложной навигационной структуре с вложенными маршрутами
<NavLink> сохраняет способность определять активность
как для родительских, так и для дочерних ссылок. Пример:
<NavLink
to="/dashboard"
className={({ isActive }) => isActive ? 'active-parent' : ''}
>
Панель
</NavLink>
<NavLink
to="/dashboard/settings"
className={({ isActive }) => isActive ? 'active-child' : ''}
>
Настройки
</NavLink>
Активность родительской ссылки можно отслеживать через проверку
isActive, или использовать специальные селекторы CSS для
стилизации дочерних элементов.
Иногда требуется более сложная логика для определения активности,
например, когда маршруты включают параметры или query-параметры. В таких
случаях можно использовать хук useMatch или
useLocation для вычисления соответствия вручную:
import { useLocation, Link } from 'react-router-dom';
function CustomLink({ to, children }) {
const location = useLocation();
const isActive = location.pathname.startsWith(to);
return (
<Link
to={to}
style={{
color: isActive ? 'red' : 'black',
fontWeight: isActive ? 'bold' : 'normal'
}}
>
{children}
</Link>
);
}
Этот подход полезен, когда нужно учитывать не только путь, но и дополнительные условия, например, query-параметры или состояние приложения.
className) для глобальной
стилизации и повторного применения CSS.style) для локальных изменений
или динамических вычислений.end для точного совпадения
маршрутов.useLocation или useMatch.Эти методы позволяют создавать навигацию, которая интуитивно показывает пользователю текущий раздел, а также легко масштабируется при добавлении новых маршрутов.