История переходов

Universal Router — это современная библиотека маршрутизации для JavaScript, предназначенная для управления навигацией в веб-приложениях. Одной из ключевых особенностей является способность отслеживать историю переходов и управлять навигационными событиями без привязки к конкретной платформе или фреймворку.

Основные концепции истории переходов

История переходов (history) — это объект, который хранит последовательность переходов пользователя между маршрутами. Universal Router не навязывает конкретную реализацию истории, позволяя использовать как встроенный объект window.history, так и сторонние реализации (например, history из пакета history).

Каждый переход содержит следующие ключевые элементы:

  • pathname — путь текущего маршрута.
  • search — строка запроса, включающая параметры URL после знака ?.
  • hash — хэш-фрагмент URL после знака #.
  • state — произвольные данные, сохраняемые вместе с переходом.

Эти элементы позволяют полностью воспроизвести состояние приложения при навигации вперед и назад.

Работа с методами истории

Universal Router интегрируется с объектами истории через методы:

  • push(path, state) — добавляет новый переход в историю.
  • replace(path, state) — заменяет текущий переход без добавления новой записи.
  • go(n) — перемещает указатель истории на n шагов вперед или назад.
  • back() / forward() — перемещает указатель на один шаг назад или вперед.

Пример использования с нативным window.history:

router.resolve({ pathname: '/about' })
  .then(() => {
    window.history.pushState({ page: 'about' }, '', '/about');
  });

Поддержка асинхронных переходов

Universal Router позволяет обрабатывать маршруты асинхронно. При этом каждый переход может быть отложен до завершения промиса:

const router = new UniversalRouter(routes, {
  context: {},
  resolveRoute(context, params) {
    return new Promise(resolve => {
      setTimeout(() => resolve(`Маршрут ${context.pathname} загружен`), 300);
    });
  }
});

router.resolve({ pathname: '/dashboard' }).then(result => console.log(result));

Асинхронные переходы интегрируются с историей, что позволяет корректно сохранять состояние приложения даже при длительных загрузках данных.

События навигации

История переходов поддерживает подписку на события. В стандартной реализации браузера используется событие popstate, которое вызывается при переходах назад и вперед. Универсальный подход позволяет создавать кастомные подписки:

window.addEventListener('popstate', event => {
  router.resolve({ pathname: window.location.pathname });
});

Каждое событие предоставляет доступ к состоянию перехода через event.state, что облегчает восстановление контекста маршрута.

Настройка собственной истории

Universal Router не ограничен встроенной историей браузера. Для серверного рендеринга или нестандартных приложений можно реализовать собственный объект истории с необходимыми методами:

class MemoryHistory {
  constructor() {
    this.stack = [];
    this.index = -1;
  }

  push(path) {
    this.stack = this.stack.slice(0, this.index + 1);
    this.stack.push(path);
    this.index++;
  }

  back() {
    if (this.index > 0) this.index--;
  }

  forward() {
    if (this.index < this.stack.length - 1) this.index++;
  }

  current() {
    return this.stack[this.index];
  }
}

const memoryHistory = new MemoryHistory();
memoryHistory.push('/home');
memoryHistory.push('/profile');
memoryHistory.back();
console.log(memoryHistory.current()); // /home

Такой подход обеспечивает полный контроль над историей и делает маршрутизацию независимой от платформы.

Сохранение состояния при переходах

Одним из преимуществ Universal Router является возможность хранить данные состояния вместе с переходами. Это позволяет реализовать:

  • Запоминание формы пользователя при навигации между страницами.
  • Поддержку сложных интерфейсов с динамическим контентом.
  • Восстановление состояния после обновления страницы.

Пример:

window.history.pushState({ formData: { name: 'Иван' } }, '', '/form');

При обработке события popstate состояние можно восстановить:

window.addEventListener('popstate', event => {
  const data = event.state?.formData;
  if (data) {
    document.querySelector('input[name="name"]').value = data.name;
  }
});

Интеграция с маршрутной логикой

История переходов тесно связана с логикой маршрутов в Universal Router. Каждый маршрут может использовать состояние истории для принятия решений о редиректах, асинхронной загрузке данных или анимации перехода. Это создаёт гибкую систему навигации, где маршруты и история работают как единый механизм управления состоянием приложения.


Такой подход делает Universal Router мощным инструментом для построения веб-приложений с динамической навигацией и полной поддержкой истории переходов.