Замена записей в истории

В TanStack Router управление историей навигации реализовано через объект history, который позволяет гибко манипулировать стэком переходов. Одним из ключевых инструментов является замена записей в истории без создания новой точки возврата. Это особенно важно для приложений, где URL должен меняться динамически, но пользовательский «назад» не должен возвращать на предыдущие состояния.


Основной принцип

В TanStack Router стандартный переход по маршруту обычно создает новую запись в истории браузера. Для замены текущей записи используется метод replace, который обновляет URL и состояние текущего маршрута без добавления новой точки в стэк:

router.navigate({
  to: '/новый-путь',
  replace: true
});

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

  • to – путь маршрута, на который происходит переход.
  • replace: true – указывает, что запись должна заменить текущую, а не добавляться в историю.

При этом все подписки на изменение маршрута срабатывают так же, как при обычной навигации, обеспечивая синхронизацию состояния приложения с URL.


Отличия от обычной навигации

Метод Создает новую запись в истории Использование
navigate({ to: path }) Да Стандартная навигация с возможностью возврата назад
navigate({ to: path, replace: true }) Нет Замена текущей записи без увеличения длины стэка

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


Использование с параметрами и состоянием

Замена записи полностью поддерживает передачу параметров маршрута и состояния:

router.navigate({
  to: '/users/:id',
  params: { id: '123' },
  search: { tab: 'profile' },
  state: { fromDashboard: true },
  replace: true
});
  • params – динамические параметры маршрута.
  • search – объект с query-параметрами.
  • state – произвольные данные, которые можно использовать в компоненте после навигации.
  • replace: true – ключевой флаг для замены текущей записи.

В этом примере URL обновится на /users/123?tab=profile, текущая запись в истории будет заменена, а доступ к состоянию можно получить через useLocation() или соответствующие хук-селекторы TanStack Router.


Практические сценарии замены записи

  1. Фильтры и сортировка Когда пользователь применяет фильтры на странице списка, URL должен обновляться, но возврат к предыдущим фильтрам через кнопку «назад» может быть нежелательным. Использование replace: true решает эту проблему.

  2. Автоматическая перенаправления После логина или подтверждения действия часто необходимо менять маршрут без возможности возврата на страницу авторизации. Замена записи гарантирует, что старый URL не останется в истории.

  3. Обновление query-параметров без перезагрузки При работе с пагинацией или сортировкой таблиц удобно обновлять URL с новым номером страницы или сортировкой, сохраняя текущее состояние приложения без добавления лишних точек возврата.


Взаимодействие с useNavigate и router.navigate

TanStack Router предоставляет несколько способов навигации:

import { useNavigate } from '@tanstack/router';

const navigate = useNavigate();

// Замена записи через хук
navigate({ to: '/dashboard', replace: true });

// Прямой вызов метода роутера
router.navigate({ to: '/dashboard', replace: true });

Оба подхода полностью эквивалентны, выбор зависит от контекста: хук удобен в компонентах React, прямой вызов метода – вне реактивных компонентов.


Обработка событий и сохранение состояния

При замене записи TanStack Router продолжает корректно работать с подписками на изменения маршрута:

router.subscribe((location) => {
  console.log('Текущий путь:', location.pathname);
});

Это позволяет автоматически реагировать на изменения URL, даже если запись заменяется и не создается новая точка возврата.


Советы по оптимизации

  • Использовать replace: true при динамическом обновлении query-параметров для предотвращения раздувания истории браузера.
  • Комбинировать с state для передачи данных между маршрутами без хранения их в URL.
  • Не злоупотреблять заменой при обычной навигации, иначе пользователь потеряет привычное поведение кнопки «назад».

Хотите, я могу подготовить отдельный подробный пример с пагинацией и фильтрацией, где replace используется для динамического изменения URL без раздувания истории? Это наглядно показывает все нюансы применения.