Урок 05

Навигация: Link, NavLink, Navigate

Link

Link — клиентская навигация без перезагрузки:

import { Link } from 'react-router-dom';

<Link to="/about">О нас</Link>
<Link to={`/posts/${post.id}`}>{post.title}</Link>

to принимает строку или объект:

<Link to={{ pathname: '/posts', search: '?page=2' }}>Посты</Link>

Не используй <a>

// Плохо: перезагрузка страницы
<a href="/about">О нас</a>

// Хорошо
<Link to="/about">О нас</Link>

<a> используй только для внешних ссылок:

<a href="https://example.com" target="_blank" rel="noopener noreferrer">
    Внешняя ссылка
</a>

NavLink

NavLink знает, активен ли маршрут:

<NavLink to="/about">О нас</NavLink>

По умолчанию добавляет класс active. Можно задать свой:

<NavLink
    to="/about"
    className={({ isActive, isPending }) =>
        isActive ? 'nav-active' : isPending ? 'nav-pending' : ''
    }
>
    О нас
</NavLink>

Стили через пропс style:

<NavLink
    to="/about"
    style={({ isActive }) => ({
        color: isActive ? 'var(--accent)' : 'inherit',
    })}
>
    О нас
</NavLink>

end

Для корневого маршрута:

<NavLink to="/" end>Главная</NavLink>

Без end корень считается активным на всех страницах.

Navigate

Navigate — декларативный редирект:

import { Navigate } from 'react-router-dom';

function ProtectedRoute({ children }: { children: React.ReactNode }) {
    const { user } = useAuth();

    if (!user) {
        return <Navigate to="/login" replace />;
    }

    return children;
}

replace — заменяет текущую запись в истории. Без него кнопка «Назад» вернёт на защищённый маршрут.

useNavigate

Программная навигация:

import { useNavigate } from 'react-router-dom';

function Form() {
    const navigate = useNavigate();

    async function handleSubmit(e: React.FormEvent) {
        e.preventDefault();
        await save();
        navigate('/posts');
    }

    return <form onSubmit={handleSubmit}>...</form>;
}

Способы:

navigate('/posts');              // переход
navigate(-1);                    // назад
navigate(1);                     // вперёд
navigate('/posts', { replace: true });

Navigate vs useNavigate

  • Navigate — в JSX, декларативный редирект
  • useNavigate — в обработчиках, императивная навигация

Передача состояния

navigate('/posts', { state: { from: 'dashboard' } });

Чтение:

import { useLocation } from 'react-router-dom';

const location = useLocation();
console.log(location.state?.from);

Итоги

  • Link — клиентская навигация
  • NavLink — активный маршрут
  • Navigate — декларативный редирект
  • useNavigate — программная навигация
  • replace — без новой записи в истории