Концепции клиентской маршрутизации

Клиентская маршрутизация — это механизм управления отображением компонентов в зависимости от URL без полной перезагрузки страницы. В Preact она реализуется через специализированные библиотеки, такие как preact-router, и поддерживает SPA-подход (Single Page Application). Основное преимущество клиентской маршрутизации заключается в улучшении UX: изменения интерфейса происходят мгновенно, а состояние приложения сохраняется между переходами.


Основы маршрутизации

В Preact маршруты определяются с помощью компонента Router, который отслеживает изменения URL и рендерит соответствующие компоненты. Синтаксис минималистичен:

import { h } from 'preact';
import { Router } from 'preact-router';
import Home from './Home';
import About from './About';

const App = () => (
  <Router>
    <Home path="/" />
    <About path="/about" />
  </Router>
);

Ключевые моменты:

  • path указывает маршрут, по которому компонент будет отображаться.
  • Компоненты внутри Router должны быть уникальными по пути.
  • Поддерживаются динамические параметры через двоеточие (:):
<Route path="/user/:id" component={UserProfile} />

Параметры маршрута автоматически передаются в пропсы компонента.


Обработка навигации

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

import { Link } from 'preact-router';

<Link href="/about">О нас</Link>

Программная навигация через объект Router:

import { route } from 'preact-router';

route('/user/123'); // Переход на маршрут /user/123

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

  • route() не вызывает перезагрузку страницы.
  • Можно передавать вторым аргументом replace для замены текущего URL в истории без добавления новой записи.

Динамические маршруты и вложенные маршруты

Динамические маршруты используют параметры для передачи данных через URL. Компонент получает параметры через пропсы:

const UserProfile = ({ id }) => <div>Профиль пользователя {id}</div>;

Вложенные маршруты позволяют строить более сложные структуры интерфейса. Например, разделение админки на вкладки:

<Router>
  <Admin path="/admin">
    <Dashboard path="/dashboard" />
    <Settings path="/settings" />
  </Admin>
</Router>

В Preact Router для вложенных маршрутов важно правильно настраивать path, чтобы дочерние компоненты корректно наследовали часть URL.


Перехват событий маршрутизации

preact-router предоставляет возможность подписываться на изменения маршрутов через событие onChange:

const handleRoute = e => {
  console.log('Переход на маршрут:', e.url);
};

<Router onCha nge={handleRoute}>
  <Home path="/" />
  <About path="/about" />
</Router>

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


Ленивая загрузка компонентов

Для улучшения производительности крупных SPA используют ленивую загрузку компонентов маршрутов:

import { lazy } from 'preact/compat';

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

<Router>
  <Home path="/" />
  <About path="/about" />
</Router>

Преимущества:

  • Уменьшение размера основного бандла.
  • Загрузка компонентов по мере необходимости.
  • Совместимость с Suspense для отображения индикатора загрузки.
import { Suspense } from 'preact/compat';

<Suspense fallback={<div>Загрузка...</div>}>
  <Router>
    <Home path="/" />
    <About path="/about" />
  </Router>
</Suspense>

Управление историей браузера

preact-router работает с History API браузера, позволяя использовать функции:

  • pushState — добавление нового состояния в историю.
  • replaceState — замена текущего состояния.
  • popstate — обработка возврата назад и вперед.

Это обеспечивает плавное взаимодействие с навигацией и поддержку кнопок браузера.


Защищённые маршруты и редиректы

Для контроля доступа к определённым маршрутам создаются защищённые компоненты:

const ProtectedRoute = ({ component: Component, isAuthenticated, ...props }) => {
  if (!isAuthenticated) {
    route('/login', true); // редирект с заменой URL
    return null;
  }
  return <Component {...props} />;
};

<Router>
  <ProtectedRoute path="/dashboard" component={Dashboard} isAuthenticated={userLoggedIn} />
</Router>

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

  • Редирект выполняется через route() с флагом replace.
  • Состояние аутентификации может храниться в контексте или глобальном хранилище.

Работа с query-параметрами

preact-router не парсит query-параметры автоматически, но их можно извлечь через стандартный URLSearchParams:

const SearchPage = ({ url }) => {
  const params = new URLSearchParams(url.split('?')[1]);
  const query = params.get('q');
  return <div>Результаты поиска для "{query}"</div>;
};

Это позволяет гибко работать с фильтрами, поиском и состоянием компонентов через URL.


Оптимизация маршрутизации

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

  • Компоненты маршрутов должны быть максимально изолированными.
  • Использовать shouldComponentUpdate или memo для предотвращения ненужных перерисовок.
  • Ленивое подключение и код-сплиттинг сокращают время начальной загрузки.

Клиентская маршрутизация в Preact обеспечивает быстрый и отзывчивый интерфейс, поддерживает динамические и вложенные маршруты, программную навигацию и интеграцию с History API. Правильная организация маршрутов и оптимизация компонентов критически важны для производительности SPA-приложений.