Интеграция с React

Page.js — это легковесная библиотека для организации маршрутизации в приложениях на JavaScript. В контексте React она используется для управления состоянием URL и рендеринга компонентов без полной перезагрузки страницы. В отличие от React Router, Page.js предоставляет более минималистичный API и прямой контроль над маршрутизацией.

Ключевой принцип: Page.js отслеживает изменения URL и вызывает зарегистрированные обработчики для соответствующих маршрутов. В React это удобно использовать для отображения компонентов на основе текущего пути.


Установка и подключение

npm install page

Импорт в компоненте:

import page from 'page';

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


Определение маршрутов

Page.js использует функцию page(path, callback). В React callback часто заменяется на рендеринг соответствующего компонента через useState или глобальный стор:

import React, { useState, useEffect } from 'react';
import page from 'page';
import Home from './Home';
import About from './About';

function App() {
  const [currentPage, setCurrentPage] = useState();

  useEffect(() => {
    page('/', () => setCurrentPage());
    page('/about', () => setCurrentPage());
    page();
  }, []);

  return (
    
{currentPage}
); } export default App;

Особенности:

  • В useEffect передаются маршруты и их обработчики.
  • Вызов page() без аргументов запускает маршрутизатор.
  • Использование состояния React позволяет автоматически перерисовывать компонент при смене маршрута.

Навигация через Page.js

Для изменения маршрута без перезагрузки страницы используется page.show(path):

Также можно интегрировать ссылки через обычные с onClick:

 { e.preventDefault(); page.show('/about'); }}>
  О нас

Это позволяет полностью контролировать переходы и сохраняет историю браузера.


Работа с параметрами маршрута

Page.js поддерживает динамические сегменты в пути:

page('/user/:id', ctx => {
  console.log(ctx.params.id);
});

В React можно использовать так:

function User({ id }) {
  return 
Пользователь: {id}
; } useEffect(() => { page('/user/:id', ctx => setCurrentPage()); page(); }, []);

ctx.params содержит все параметры, указанные в маршруте. Это позволяет создавать динамические страницы пользователей, товаров или статей.


Middleware и обработка состояний

Page.js поддерживает цепочку middleware:

page((ctx, next) => {
  console.log('URL изменился на', ctx.path);
  next();
});

page('/dashboard', ctx => setCurrentPage());
page();
  • Middleware вызывается перед обработчиком маршрута.
  • Можно использовать для авторизации, логирования или предварительной загрузки данных.

Асинхронная загрузка данных

Часто страницы React требуют предварительной загрузки данных:

page('/profile/:id', async ctx => {
  const response = await fetch(`/api/users/${ctx.params.id}`);
  const data = await response.json();
  setCurrentPage();
});

Особенности:

  • Поддерживается асинхронность благодаря современному синтаксису async/await.
  • Маршрутизация остаётся отзывчивой, так как Page.js управляет состоянием URL независимо от загрузки данных.

Синхронизация с историей браузера

Page.js использует HTML5 History API. Для корректной работы с React:

page.base('/app'); // если приложение находится в подкаталоге
page({ hashbang: false }); // отключение хеш-маршрутов
  • page.base(path) задаёт базовый путь для всех маршрутов.
  • Можно легко комбинировать с серверной поддержкой маршрутов, чтобы при обновлении страницы сервер возвращал index.html.

Советы по архитектуре

  1. Централизованный модуль маршрутизации

    • Создать отдельный файл routes.js для всех маршрутов и middleware.
    • Избегает дублирования кода и упрощает поддержку приложения.
  2. Использование состояний React

    • Хранить текущий компонент в состоянии React или использовать глобальный стор (Redux, Zustand) для управления маршрутизацией.
  3. Lazy loading компонентов

    • Комбинировать с React.lazy и Suspense для оптимизации загрузки больших приложений.
  4. Middleware для авторизации

    • Перед рендерингом защищённых страниц проверять токен или сессию пользователя через middleware.

Пример расширенного приложения

import React, { useState, useEffect, Suspense, lazy } from 'react';
import page from 'page';

const Home = lazy(() => import('./Home'));
const About = lazy(() => import('./About'));
const Profile = lazy(() => import('./Profile'));

function App() {
  const [currentPage, setCurrentPage] = useState(null);

  useEffect(() => {
    page('*', ctx => console.log('Переход на', ctx.path));
    page('/', () => setCurrentPage());
    page('/about', () => setCurrentPage());
    page('/profile/:id', async ctx => {
      const data = await fetch(`/api/users/${ctx.params.id}`).then(r => r.json());
      setCurrentPage();
    });
    page();
  }, []);

  return (
    Загрузка...
}> {currentPage} ); } export default App;

Этот подход позволяет использовать преимущества динамической маршрутизации Page.js, интегрируя их с современными возможностями React, включая ленивую загрузку компонентов и асинхронную работу с API.