Page.js — это лёгкая клиентская библиотека для организации маршрутизации в одностраничных приложениях (SPA). Одной из ключевых возможностей является передача состояния между маршрутами, что позволяет хранить и передавать данные без использования глобальных переменных или URL-параметров. Рассмотрим детально, как это реализуется и какие есть нюансы.
При использовании Page.js маршруты определяются через функцию
page(path, callback), где callback принимает
объект контекста ctx и функцию next. Контекст
содержит важные данные о текущем маршруте. Для передачи state при
навигации можно использовать объект ctx.state, который
создаётся и доступен в каждом обработчике маршрута.
page('/profile', (ctx) => {
console.log(ctx.state.user); // Доступ к переданным данным
});
Чтобы передать state при переходе на маршрут, используется метод
page.show(path, state):
const user = { id: 1, name: 'Alice' };
page.show('/profile', { user });
В этом примере объект { user } автоматически попадает в
ctx.state при обработке маршрута /profile.
Ключевые моменты:
ctx.state создаётся автоматически при вызове
page.show.Каждый вызов page.show создаёт новый объект
ctx. Если передан state, он присваивается
ctx.state. Это значит, что:
ctx.params для
более сложной маршрутизации.page('/post/:id', (ctx) => {
console.log(ctx.params.id); // параметр из URL
console.log(ctx.state.comments); // данные из предыдущего маршрута
});
Такой подход позволяет хранить данные, не захламляя адресную строку, и управлять состоянием приложения централизованно.
Чаще всего state передаётся при программной навигации через кнопки, ссылки или события:
document.querySelector('#btnProfile').addEventListener('click', () => {
const userData = { id: 42, name: 'Bob' };
page.show('/profile', { user: userData });
});
Если пользователь кликает по ссылке
<a href="/profile">, данные state не
передаются автоматически. В этом случае есть два решения:
onclick обработчик и вызвать
page.show с state.localStorage/sessionStorage.Прямое использование <a> работает только для
URL-перехода, state здесь не поддерживается.
Page.js позволяет подключать промежуточные обработчики (middleware)
через page(fn) или цепочку вызовов маршрутов. Передаваемый
state доступен на всех уровнях цепочки.
page('*', (ctx, next) => {
console.log('Global middleware', ctx.state);
next();
});
page('/dashboard', (ctx) => {
console.log('Dashboard', ctx.state.user);
});
page.show('/dashboard', { user: { name: 'Alice' } });
Особенности:
ctx.state одинаковый для всех middleware и конечного
обработчика маршрута.ctx.state в middleware отражается в
последующих обработчиках.Если нужно сохранить оригинальный state и добавить новые данные, рекомендуется клонировать объект перед модификацией:
page('/settings', (ctx) => {
const newState = { ...ctx.state, theme: 'dark' };
page.show('/profile', newState);
});
Это позволяет избежать непреднамеренного изменения state других маршрутов и гарантирует чистоту данных.
localStorage или сервер.// Middleware для логина
page('*', (ctx, next) => {
ctx.state.user = { id: 123, name: 'Alice' };
next();
});
// Маршрут профиля
page('/profile', (ctx) => {
const { user } = ctx.state;
document.body.innerHTML = `<h1>Профиль: ${user.name}</h1>`;
});
// Переход с кнопки
document.querySelector('#btnProfile').addEventListener('click', () => {
page.show('/profile', { extra: 'Дополнительные данные' });
});
В этом примере:
page.show.ctx.state объединяет данные middleware и
переданные вручную.Использование ctx.state делает маршрутизацию в Page.js
гибкой и безопасной для передачи внутренних данных приложения без
зависимости от URL, облегчая работу с динамическим интерфейсом SPA.