Глобальное состояние приложения

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


Роль глобального состояния

Глобальное состояние — это структура данных, доступная из любого места приложения. В Page.js оно часто используется для:

  • Хранения информации о текущем маршруте (currentPath, params, query);
  • Синхронизации видимых компонентов с URL;
  • Передачи данных между обработчиками маршрутов и компонентами без прямого связывания.

Структура глобального состояния

Чаще всего глобальное состояние оформляется как объект:

const state = {
  currentPath: '/',
  params: {},
  query: {},
  user: null,
  settings: {}
};
  • currentPath — текущий путь маршрута;
  • params — параметры маршрута (/user/:id);
  • query — параметры запроса (?filter=active);
  • user — данные о текущем пользователе;
  • settings — пользовательские настройки приложения.

Такой объект можно хранить в модуле, экспортировать и использовать во всех частях приложения.


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

Page.js предоставляет функцию page() для определения маршрутов:

page('/user/:id', ctx => {
  state.currentPath = ctx.path;
  state.params = ctx.params;
  state.query = ctx.querystring;
  renderUser(ctx.params.id);
});
  • ctx.path — полный путь запроса;
  • ctx.params — объект с параметрами маршрута;
  • ctx.querystring — строка запроса (можно парсить с помощью URLSearchParams).

Таким образом, глобальное состояние автоматически синхронизируется с URL.


Реактивное отслеживание изменений состояния

Для SPA важно, чтобы изменения состояния вызывали обновление интерфейса. Один из подходов — использование подписчиков:

const listeners = [];

function subscribe(listener) {
  listeners.push(listener);
}

function setState(newState) {
  Object.assign(state, newState);
  listeners.forEach(fn => fn(state));
}

Пример применения:

subscribe(state => {
  renderHeader(state.user);
  renderSettingsPanel(state.settings);
});

Теперь любое обновление через setState автоматически обновляет все части интерфейса, связанные с состоянием.


Глобальное состояние и асинхронные данные

Часто маршруты требуют загрузки данных с сервера:

page('/posts/:id', async ctx => {
  state.currentPath = ctx.path;
  state.params = ctx.params;
  
  const response = await fetch(`/api/posts/${ctx.params.id}`);
  const post = await response.json();
  
  setState({ currentPost: post });
});

Использование setState обеспечивает, что данные поста попадут в глобальное состояние и интерфейс обновится автоматически.


Согласование маршрутов и состояния

Page.js предоставляет методы page.redirect() и page.show() для управления переходами. При изменении маршрута состояние также должно обновляться:

function navigateTo(path) {
  page.show(path);
  state.currentPath = path;
}

Это гарантирует, что глобальное состояние всегда соответствует URL, а интерфейс — визуально консистентен.


Разделение состояния на модули

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

// state/user.js
export const userState = {
  data: null,
  isLoggedIn: false
};

// state/settings.js
export const settingsState = {
  theme: 'light',
  notifications: true
};

Каждый модуль может иметь свои подписки и функции обновления, что упрощает управление сложными состояниями.


Интеграция с компонентами

Компоненты могут напрямую использовать глобальное состояние через импорт:

import { state } from './state';

function renderHeader() {
  const header = document.querySelector('header');
  header.textContent = state.user ? `Привет, ${state.user.name}` : 'Добро пожаловать';
}

Использование подписок позволяет автоматически перерисовывать компоненты при изменении состояния, создавая реактивное поведение без дополнительных библиотек.


URL-параметры и глобальное состояние

Особое внимание уделяется параметрам маршрута и query-параметрам:

page('/search', ctx => {
  const query = new URLSearchParams(ctx.querystring);
  setState({ searchQuery: query.get('q') });
});

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


Вывод

Глобальное состояние в Page.js обеспечивает:

  • Централизованное хранение данных;
  • Синхронизацию интерфейса с URL;
  • Поддержку реактивного обновления компонентов;
  • Управление асинхронными запросами и параметрами маршрутов.

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