Библиотека Universal Router предоставляет гибкий
механизм маршрутизации для JavaScript-приложений, позволяя описывать
маршруты в виде объектов с определёнными свойствами, включая
path, action, children и другие.
Одним из ключевых аспектов работы является возвращаемое значение
функции action, которая выполняется при совпадении
маршрута. Понимание типов возвращаемых значений позволяет строить
сложные и масштабируемые маршруты, интегрировать асинхронные операции и
управлять логикой навигации.
Самый простой и распространённый вариант — непосредственное
возвращение результата из action. Это может быть
любой тип данных: строка, объект, число, HTML-шаблон и т.п.
import UniversalRouter from 'universal-router';
const routes = [
{
path: '/home',
action: () => 'Главная страница'
},
{
path: '/about',
action: () => ({ title: 'О нас', content: 'Информация о компании' })
}
];
const router = new UniversalRouter(routes);
router.resolve('/home').then(result => console.log(result));
// Выведет: "Главная страница"
Особенности:
Функция action может быть асинхронной,
возвращая Promise. Это особенно полезно, когда требуется
загрузка данных с сервера, чтение локального хранилища или выполнение
других асинхронных операций перед рендерингом.
const routes = [
{
path: '/profile/:id',
action: async ({ params }) => {
const response = await fetch(`/api/user/${params.id}`);
const data = await response.json();
return data;
}
}
];
const router = new UniversalRouter(routes);
router.resolve('/profile/123').then(user => console.log(user));
Ключевые моменты:
async/await внутри
action для удобства.Возвращаемое значение может быть результатом вызова
вложенного маршрута, используя объект
router.resolve внутри action. Такой подход
полезен для маршрутов с вложенной структурой, когда часть логики
маршрутизации делегируется дочернему маршруту.
const routes = [
{
path: '/dashboard',
children: [
{
path: '/stats',
action: () => 'Статистика'
}
],
action: (context, next) => next()
}
];
const router = new UniversalRouter(routes);
router.resolve('/dashboard/stats').then(console.log);
// Выведет: "Статистика"
Особенности:
next() вызывает обработку дочерних маршрутов.next() не вызывается, обработка останавливается на
текущем маршруте.Функция action может возвращать другую
функцию, которая затем вызывается в контексте рендеринга или
дополнительной логики. Это позволяет строить ленивые вычисления и
использовать паттерн “функция-генератор” для маршрутов.
const routes = [
{
path: '/lazy',
action: () => () => 'Ленивая загрузка контента'
}
];
router.resolve('/lazy').then(result => {
console.log(result()); // Выведет: "Ленивая загрузка контента"
});
Преимущества:
null
или undefinedЕсли action возвращает null или
undefined, Universal Router интерпретирует это как
отсутствие результата для текущего маршрута. В сочетании с
next() это позволяет пропускать маршруты, передавая
обработку выше по цепочке или к дочерним маршрутам.
const routes = [
{
path: '/optional',
action: (context, next) => {
if (!context.user) return null;
return next();
}
}
];
Особенности:
Для сложных интерфейсов полезно возвращать структурированные объекты, которые содержат как данные, так и инструкции по отображению:
const routes = [
{
path: '/page',
action: () => ({
title: 'Страница',
template: '<div>Контент</div>',
scripts: ['/js/page.js']
})
}
];
Преимущества:
Возвращаемое значение может быть объектом с ключом
redirect, что позволяет осуществлять
перенаправление:
const routes = [
{
path: '/old',
action: () => ({ redirect: '/new' })
}
];
Возвращение ошибки из action реализуется через
генерацию исключения, которое можно обрабатывать при
вызове resolve:
const routes = [
{
path: '/secure',
action: () => {
throw new Error('Доступ запрещён');
}
}
];
router.resolve('/secure').catch(err => console.error(err.message));
// Выведет: "Доступ запрещён"
next() для выбора альтернативного
маршрута при ошибке.Типы возвращаемых значений в Universal Router обеспечивают максимальную гибкость при построении маршрутов: от простых синхронных строк до асинхронных промисов, функций, объектов с метаданными и редиректов. Правильное использование этих возможностей позволяет строить масштабируемые и динамические приложения с централизованной логикой маршрутизации.