В библиотеке Universal Router хуки
before и after предоставляют мощный механизм
для управления поведением маршрутов до и после их обработки. Эти хуки
позволяют внедрять общую логику в маршруты, не дублируя код в каждом
обработчике. Они особенно полезны для авторизации, логирования,
обработки ошибок, отслеживания переходов и асинхронных операций.
beforeХук before вызывается перед обработкой
маршрута, и его задача — определить, может ли маршрут быть
выполнен, или изменить контекст выполнения. Он принимает два
параметра:
before(context, next)
pathname, query,
params, route и другие свойства.Promise.const router = new UniversalRouter(routes, {
before: async (context, next) => {
if (context.pathname.startsWith('/admin')) {
const user = await getUser();
if (!user.isAdmin) {
return '/login';
}
}
return next();
}
});
В этом примере любой переход к /admin проверяется на
права администратора. Если проверка не проходит, происходит редирект на
/login.
before: (context, next) => {
context.startTime = Date.now();
return next();
}
Добавление временной метки позволяет замерять производительность
маршрута в хуке after.
before: async (context, next) => {
context.userData = await fetchUserData();
return next();
}
Все обработчики маршрута получают заранее подготовленные данные, что упрощает архитектуру приложения.
next() — продолжить выполнение
маршрута.Promise — позволяет использовать
асинхронные проверки и подгрузку данных.afterХук after вызывается после того, как маршрут был
обработан и результат маршрута сформирован. Он позволяет
модифицировать результат или выполнить побочные эффекты. Сигнатура:
after(context, result)
before.after: (context, result) => {
console.log(`Маршрут ${context.pathname} завершен с результатом:`, result);
return result;
}
С помощью этого подхода можно отслеживать успешные и неуспешные переходы в приложении.
after: (context, result) => {
const duration = Date.now() - context.startTime;
console.log(`Время выполнения маршрута: ${duration}ms`);
return result;
}
Хук after идеально подходит для профилирования и
оптимизации.
after: (context, result) => {
if (typeof result === 'string') {
return result.toUpperCase();
}
return result;
}
Позволяет изменять результат маршрута перед его отображением или отправкой пользователю.
const router = new UniversalRouter(routes, {
before: globalBeforeHook,
after: globalAfterHook
});
{
path: '/profile',
action: () => 'Profile Page',
before: (ctx, next) => { /* локальная проверка */ return next(); },
after: (ctx, result) => { /* локальная обработка результата */ return result; }
}
Логика выполнения: сначала вызываются глобальные хуки, затем локальные.
Хуки before и after полностью поддерживают
Promise. Если внутри before вызывается
асинхронная операция, Universal Router дождется её завершения:
before: async (context, next) => {
const allowed = await checkAccess(context.user);
if (!allowed) return '/403';
return next();
}
Хук after также может быть асинхронным, например, для
записи логов на сервер:
after: async (context, result) => {
await sendAnalytics(context.pathname, result);
return result;
}
before может полностью прервать выполнение
маршрута, возвращая новый путь или результат.after не влияет на переход, только
на результат.try/catch или глобальные обработчики ошибок
маршрутизатора.context является единым объектом для всех хуков и
обработчиков маршрута, что позволяет передавать данные между
before, action и after.before для проверок, авторизации,
подгрузки данных и редиректов.after для логирования, аналитики,
модификации результатов и выполнения побочных эффектов.Promise, чтобы избежать неконсистентного поведения.Хуки before и after создают универсальный
инструмент для контроля маршрутов и позволяют выстраивать чистую
архитектуру приложения, делая маршрутизатор гибким, безопасным и
легко расширяемым.