Тестирование хуков

В библиотеке Navigo хуки представляют собой специальные функции, которые позволяют перехватывать процесс навигации и выполнять дополнительные действия до или после изменения маршрута. Хуки делятся на несколько типов: before, after, already, error, и каждый из них имеет своё предназначение и область применения. Использование хуков повышает контроль над жизненным циклом маршрутов и позволяет реализовать сложную логику, например, проверку авторизации или динамическую подгрузку данных.


Хук before

Хук before вызывается перед активацией маршрута. Он принимает два параметра: объект done и объект params.

Сигнатура:

router.hooks({
  before: (done, params) => {
    // логика до смены маршрута
    done();
  }
});

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

  • Позволяет остановить или перенаправить навигацию.
  • Используется для проверки условий, например, авторизации пользователя.
  • Если done() не вызывается, переход по маршруту не произойдет.

Пример использования:

router.hooks({
  before: (done, params) => {
  if (!user.isAuthenticated()) {
      router.navigate('/login');
  } else {
      done();
  }
  }
});

В этом примере переход на защищённый маршрут блокируется для неавторизованного пользователя.


Хук after

Хук after вызывается после того, как маршрут активирован и отрендерен. Он полезен для выполнения побочных эффектов, которые не влияют на саму навигацию.

Сигнатура:

router.hooks({
  after: (params) => {
    console.log('Маршрут активирован', params);
  }
});

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

  • Не влияет на процесс навигации.
  • Часто используется для логирования, аналитики и инициализации сторонних библиотек после загрузки контента.
  • Получает объект параметров маршрута, что позволяет использовать динамические данные.

Хук already

Хук already срабатывает, если пользователь пытается перейти на текущий маршрут. По умолчанию Navigo игнорирует такие переходы, но с хуком можно обработать повторный вызов.

Пример:

router.hooks({
  already: (params) => {
    console.log('Пользователь снова на этом маршруте', params);
  }
});

Используется для:

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

Хук error

Хук error позволяет обрабатывать ошибки навигации, например, если маршрут не найден или возникла проблема в callback-функции маршрута.

Сигнатура:

router.hooks({
  error: (error) => {
    console.error('Ошибка маршрутизации', error);
    router.navigate('/404');
  }
});

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

  • Можно использовать для глобальной обработки ошибок маршрутов.
  • Позволяет перенаправлять пользователя на страницу ошибки или логировать исключения.

Последовательность вызова хуков

При навигации в Navigo порядок вызова хуков следующий:

  1. before – проверка условий и возможность остановить навигацию.
  2. Если before завершён через done(), маршрут активируется.
  3. already – если переход был на текущий маршрут.
  4. after – выполнение побочных действий после активации маршрута.
  5. error – вызывается при любой ошибке в процессе.

Использование хуков с динамическими маршрутами

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

Пример с динамическим параметром:

router
  .on('/profile/:userId', ({ userId }) => {
    console.log('Загрузка профиля пользователя', userId);
  })
  .hooks({
    before: (done, params) => {
      if (!isValidUser(params.userId)) {
        router.navigate('/not-found');
      } else {
        done();
      }
    },
    after: (params) => {
      console.log('Профиль загружен', params.userId);
    }
  });

В этом примере:

  • before проверяет существование пользователя перед загрузкой страницы.
  • after выполняет действия после успешной загрузки.

Комбинация нескольких хуков

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

Пример:

router.hooks({
  before: (done, params) => {
    console.log('Перед маршрутом', params);
    done();
  },
  after: (params) => {
    console.log('После маршрута', params);
  },
  already: (params) => {
    console.log('Уже на маршруте', params);
  },
  error: (err) => {
    console.error('Ошибка маршрута', err);
  }
});

Это позволяет централизованно управлять навигацией и реакциями на события.


Особенности тестирования хуков

Тестирование хуков требует изоляции логики от реальной навигации. Основные подходы:

  1. Мокирование объекта Router:

    • Подменять методы navigate и on для проверки вызова хуков.
  2. Проверка последовательности вызовов:

    • Использовать флаги или счетчики для убеждения, что хуки вызываются в правильном порядке.
  3. Асинхронные хуки:

    • Для асинхронных операций (например, проверки авторизации через API) важно вызывать done() после завершения, иначе тесты будут застывать.

Пример теста с Jest:

test('before hook останавливает переход при ошибке', () => {
  const done = jest.fn();
  const params = {};
  const beforeHook = (done, params) => {
    done();
  };
  beforeHook(done, params);
  expect(done).toHaveBeenCalled();
});

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

  • Использовать before для проверок и редиректов, after для побочных эффектов.
  • Не перегружать хуки тяжелыми вычислениями – они блокируют навигацию.
  • Для повторного использования логики создавать отдельные функции и подключать их к хукам.
  • Всегда обрабатывать исключения в хуках, чтобы не нарушить работу маршрутизатора.

Хуки в Navigo позволяют выстраивать гибкую архитектуру SPA и централизованно управлять всеми этапами навигации. Их грамотное использование обеспечивает контроль, безопасность и удобство поддержки маршрутов.