Восстановление состояния при навигации

Page.js предоставляет гибкий механизм для управления маршрутами в одностраничных приложениях (SPA). Одной из важных задач при создании SPA является восстановление состояния интерфейса при навигации назад и вперед, чтобы пользователь не терял контекст при переходах между страницами.

Управление состоянием через ctx.state

Каждый маршрут в Page.js получает объект ctx (контекст), который содержит всю информацию о текущем маршруте: путь, параметры, query-параметры и пользовательское состояние. Поле ctx.state используется для хранения и передачи состояния между маршрутами.

Пример использования:

page('/profile', (ctx, next) => {
  // Восстанавливаем состояние из ctx.state, если оно было сохранено
  const savedScroll = ctx.state.scrollTop || 0;
  document.querySelector('.content').scrollTop = savedScroll;

  // Сохраняем новое состояние перед навигацией
  ctx.state.scrollTop = document.querySelector('.content').scrollTop;
});

Здесь ctx.state.scrollTop позволяет запомнить позицию прокрутки при уходе со страницы и восстановить её при возвращении.

Передача состояния при навигации

Page.js позволяет передавать пользовательское состояние при переходе с помощью второго аргумента метода page.show:

page.show('/profile', { scrollTop: 200 });

При этом в целевом маршруте это состояние доступно через ctx.state:

page('/profile', (ctx) => {
  const scroll = ctx.state.scrollTop || 0;
  document.querySelector('.content').scrollTop = scroll;
});

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

Работа с кнопками “Назад” и “Вперед”

Page.js автоматически интегрируется с HTML5 History API. Каждое изменение маршрута через page.show() или пользовательскую навигацию с кнопками браузера генерирует событие popstate, что позволяет восстанавливать состояние при возврате на предыдущую страницу.

Для корректного восстановления состояния можно использовать ctx.state совместно с обработчиком события popstate:

page('/dashboard', (ctx) => {
  const filters = ctx.state.filters || {};
  applyFilters(filters);
});

window.addEventListener('popstate', (event) => {
  if (event.state) {
    page.show(location.pathname, event.state);
  }
});

В этом примере состояние фильтров сохраняется при навигации и восстанавливается при нажатии кнопок “Назад” или “Вперед”.

Сохранение состояния в локальное хранилище

Для долгосрочного сохранения состояния между сессиями или после перезагрузки страницы можно комбинировать ctx.state с localStorage или sessionStorage:

page('/settings', (ctx) => {
  const savedState = JSON.parse(localStorage.getItem('settingsState')) || {};
  restoreSettings(savedState);

  document.querySelector('#saveButton').oncl ick = () => {
    const newState = collectSettings();
    localStorage.setItem('settingsState', JSON.stringify(newState));
    ctx.state.settings = newState;
  };
});

Такое решение обеспечивает сохранение пользовательских настроек не только при навигации внутри SPA, но и при перезагрузке страницы.

Использование middleware для восстановления состояния

Для унификации восстановления состояния рекомендуется создавать middleware, который автоматически применяет сохранённое состояние к компонентам страницы:

function restoreScroll(ctx, next) {
  if (ctx.state.scrollTop) {
    document.querySelector('.content').scrollTop = ctx.state.scrollTop;
  }
  next();
}

page('*', restoreScroll);

Любой маршрут, подключённый после этого middleware, будет автоматически восстанавливать позицию прокрутки без необходимости дублировать код.

Важные рекомендации

  • Хранить только критическое состояние. Не следует сохранять большие объёмы данных в ctx.state, это может замедлять навигацию и потреблять память.
  • Использовать JSON-сериализацию для долговременного хранения в localStorage или sessionStorage.
  • Комбинировать ctx.state с middleware для централизованного контроля состояния, особенно для элементов UI, таких как вкладки, формы, фильтры и списки.
  • Соблюдать согласованность ключей состояния между маршрутами, чтобы избежать конфликтов и неожиданных перезаписей.

Заключение по практике восстановления состояния

Page.js предоставляет гибкий, но простой способ сохранять и восстанавливать состояние интерфейса при навигации. Основной инструмент — это ctx.state и интеграция с History API. Комбинация middleware, передачи состояния через page.show() и долговременного хранения в localStorage позволяет создавать SPA с плавной навигацией и удобным пользовательским опытом, без потери контекста между страницами.

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