5 - Хук useRouter для навигации в Next.js

Для доступа к видео войдите в систему

5 - Хук useRouter для навигации в Next.js

Оценить качество материала и подачу материала автором видео:

Front-end

Трудоустройтесь middle front-end разработчиком на React JS (TypeScript) за 12-16 месяцев обучения с ежедневной менторской поддержкой в формате видео 1 на 1 и коммерческими проектами в портфолио

Перейти на курс
Front-end

Back-end

Трудоустройтесь middle back-end разработчиком за 12-16 месяцев обучения с ежедневной менторской поддержкой в формате видео 1 на 1 и коммерческими проектами в портфолио

Перейти на курс
Back-end

Карьерный бустер

Получите коммерческий опыт на реальных стартапах, прокачайте tech & soft навыки, научитесь работать в команде, проходить собеседования и получите первую работу в IT!

Перейти на курс
Карьерный бустер

Основы Front-end

Сделайте первый шаг в IT, освоив базовые знания разработки и научившись создавать небольшие проекты на JavaScript

Перейти на курс
Основы Front-end

Основы Back-end

Сделайте первый шаг в IT, освоив базовые знания разработки. Без опыта. Без математики. Только практика: JavaScript, SQL, Node JS, база данных

Перейти на курс
Основы Back-end

useRouter Next.js: Полный Гайд по Навигации Push vs Replace + Скролл

Автор конспекта: Стогниева Виктория

1. Введение: Программная навигация в Next.js 🧭

В экосистеме Next.js компонент <Link> является стандартным решением для декларативной навигации между страницами. Однако его возможностей не всегда достаточно. Возникают сценарии, когда переход нужно инициировать программно, например, после успешной отправки формы, завершения асинхронной операции или в ответ на любое другое событие в логике компонента. Именно для таких задач предназначен хук useRouter — ключевой инструмент для императивного управления переходами в приложении.

Этот гайд предоставит вам исчерпывающее понимание работы с useRouter. Мы детально рассмотрим:

  • Инициализацию хука в клиентских компонентах App Router.
  • Принципиальную разницу между основными методами навигации — push и replace.
  • Управление поведением прокрутки страницы для создания бесшовного пользовательского опыта.

2. Основы работы с useRouter ⚙️

Хук useRouter — это основной инструмент для выполнения программной навигации в клиентских компонентах Next.js. Он предоставляет объект с методами, которые позволяют перенаправлять пользователя, управлять историей браузера и многое другое.

Первым и самым важным шагом является его правильный импорт и инициализация. Будьте внимательны: современные IDE иногда могут ошибочно предложить импорт из next/router, который предназначен для старой архитектуры Pages Router. В App Router всегда используйте next/navigation.

Для современных приложений, использующих App Router, критически важно импортировать хук из next/navigation. Импорт из next/router предназначен для старой архитектуры и не будет работать корректно в новых проектах.

Базовая настройка в компоненте выглядит следующим образом:

tsx
"use client"
 
import { useRouter } from "next/navigation"
 
export default function NavigationComponent() {
  const router = useRouter()
 
  // ... остальная логика компонента, использующая router
}

После этой простой инициализации константа router содержит экземпляр роутера, предоставляя доступ ко всем необходимым методам. Рассмотрим два самых важных из них.

3. Ключевые методы: push против replace 🔄

На первый взгляд, методы router.push() и router.replace() выполняют одну и ту же задачу — перенаправляют пользователя на новую страницу. Однако под капотом они работают принципиально по-разному, и это отличие напрямую влияет на пользовательский опыт. Центральный вопрос этого раздела: в чем их разница и как выбрать подходящий метод для создания интуитивно понятной и предсказуемой навигации?

3.1. Метод router.push(): Добавление в историю ➕

Метод router.push() является наиболее распространенным способом программной навигации. Он не просто перенаправляет пользователя на новый URL, но и добавляет этот URL в стек истории браузера.

Такое поведение означает, что пользователь сможет без проблем вернуться на предыдущую страницу, нажав стандартную кнопку "Назад" в своем браузере. Это делает push идеальным выбором для большинства переходов, таких как переход к карточке товара, в профиль пользователя или на другую информационную страницу.

Практический пример:

tsx
"use client"
 
import { useRouter } from "next/navigation"
import styles from "./header.module.css"
 
export const Header = () => {
  const router = useRouter()
 
  return (
    <nav className={styles.navigation}>
      <ul>
        <li>
          <button onClick={() => router.push("/")} className={styles.link}>
            Main
          </button>
        </li>
        <li>
          <button onClick={() => router.push("/profile")} className={styles.link}>
            Profile
          </button>
        </li>
        <li>
          <button onClick={() => router.push("/profile/123")} className={styles.link}>
            Profile 123
          </button>
        </li>
      </ul>
    </nav>
  )
}

3.2. Метод router.replace(): Замена в истории 🔄

В отличие от push, метод router.replace() заменяет текущий URL в стеке истории браузера новым URL, а не добавляет его.

Ключевое последствие такого подхода заключается в том, что пользователь не сможет вернуться на страницу, с которой был выполнен переход, с помощью кнопки "Назад". Запись о ней была буквально стерта из истории посещений.

Используйте этот метод только в тех сценариях, где возврат на предыдущую страницу нарушает логику приложения. Классический пример — перенаправление на страницу профиля после успешного входа. Использование push здесь было бы ошибкой, так как позволило бы пользователю вернуться на страницу логина, создавая некорректный и запутанный пользовательский опыт.

3.3. Практическое сравнение и навигация по истории 📚

Разницу между push и replace легко продемонстрировать с помощью вспомогательных методов router.back() и router.forward(). Они программно эмулируют нажатие кнопок "Назад" и "Вперед" в браузере и могут быть привязаны к кнопкам в вашем интерфейсе для создания кастомных элементов управления навигацией.

tsx
"use client"
 
import { useRouter } from "next/navigation"
import styles from "./header.module.css"
 
export const Header = () => {
  const router = useRouter()
 
  return (
    <nav className={styles.navigation}>
      <ul>
        <li>
          <button onClick={() => router.back()} className={styles.link}>
            Back
          </button>
        </li>
        <li>
          <button onClick={() => router.push("/")} className={styles.link}>
            Main
          </button>
        </li>
        <li>
          <button onClick={() => router.push("/profile")} className={styles.link}>
            Profile
          </button>
        </li>
        <li>
          <button onClick={() => router.push("/profile/123")} className={styles.link}>
            Profile 123
          </button>
        </li>
        <li>
          <button onClick={() => router.forward()} className={styles.link}>
            Forward
          </button>
        </li>
      </ul>
    </nav>
  )
}

Для наглядности сведем ключевые отличия в таблицу:

КритерийОписание
Поведениеpush: Добавляет URL в стек истории браузера.
replace: Заменяет текущий URL в стеке истории, не создавая новой записи.
Влияние на кнопку "Назад"push: Пользователь может вернуться на предыдущую страницу.
replace: Пользователь не может вернуться на предыдущую страницу, так как она удалена из истории.
Основной сценарийpush: Стандартная навигация, где возврат ожидаем (просмотр статей, переход в профиль).
replace: Предотвращение возврата к промежуточным состояниям (после логина, смены языка, шаги в многоэтапной форме).

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

4. Управление поведением скролла при навигации 📜

По умолчанию Next.js обеспечивает удобное для пользователя поведение: при любом переходе на новую страницу окно браузера автоматически прокручивается вверх. Это разумный стандарт, поскольку пользователь ожидает увидеть начало нового контента.

Однако в некоторых случаях это поведение требуется переопределить. Методы навигации, такие как push, принимают второй, необязательный аргумент — объект с опциями, который позволяет управлять поведением скролла.

Чтобы отключить автоматическую прокрутку вверх, достаточно передать опцию { scroll: false }. В этом случае Next.js сохранит текущую позицию прокрутки при переходе на новую страницу. Это особенно полезно в следующих сценариях:

  • Каталоги с фильтрами или пагинацией: пользователь сохраняет свое место в длинном списке товаров после применения фильтра.
  • Интерфейсы с вкладками: при переключении между вкладками, которые меняют URL, но являются частью одной длинной страницы.
  • Бесконечная прокрутка: для сохранения контекста при подгрузке и отображении новых данных.

Пример вызова с отключенным скроллом:

tsx
router.push("/profile/123", { scroll: false })

5. Заключение: Ключевые выводы ✅

Освоение программной навигации с помощью хука useRouter открывает широкие возможности для создания сложных и интерактивных веб-приложений на Next.js. Подведем итог ключевым моментам, рассмотренным в этом гайде:

  • Основа навигации: Используйте хук useRouter из next/navigation для всех программных переходов в клиентских компонентах App Router.
  • Критическая разница push vs replace: push сохраняет историю для навигации "назад", в то время как replace заменяет её, что идеально для таких сценариев, как редирект после логина.
  • Контроль UX: Отключайте скролл вверх с помощью опции { scroll: false } для сохранения контекста пользователя при переходах на страницах с большим количеством контента.

useRouter — это лишь один из инструментов для создания сложных потоков данных и навигации. Его освоение открывает путь к более продвинутым паттернам, таким как управление состоянием через параметры URL или интеграция с серверными компонентами. Уверенное владение этими инструментами — это то, что отличает продуманный пользовательский опыт от стандартного, позволяя вам создавать по-настоящему профессиональные и интуитивно понятные приложения на Next.js. 🚀