0Pricing
React Academy · Урок

Создание пользовательского хука useThrottle

Создайте хук useThrottle, ограничивающий частоту обновления значения во время быстрых событий, например прокрутки

«Создание пользовательского хука useThrottle» — бесплатный урок React Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения React Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс React Academy содержит 4 уроков всего.

Ограничение частоты сложнее отложенного вызова

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

Использование useRef для lastRunTime

Отметка времени последнего выполнения должна сохраняться между рендерингами, не вызывая сама по себе повторных рендерингов, поэтому useRef — подходящий инструмент. Сохраните отметку времени так: const lastRunTime = useRef(Date.now()). В отличие от состояния, обновление ссылки не вызывает повторный рендеринг, поэтому логика ограничения частоты работает эффективно, без лишних циклов.

Сигнатура хука

Хук useThrottle(value, delay) возвращает ограниченную по частоте версию входного значения. Его контракт похож на контракт useDebounce: принять любое значение и задержку в мс, а вернуть значение с ограниченной частотой обновления. Компоненты используют его так же, поэтому он служит прямой заменой при необходимости другой логики интервалов.

Реализация отложенного режима

Ограничитель частоты с отложенным обновлением обновляет значение в конце каждого интервала. Когда поступает новое значение, запланируйте setTimeout на оставшееся время интервала: delay - (Date.now() - lastRunTime.current). Когда таймер срабатывает, обновите состояние и сохраните новое значение lastRunTime. В функции очистки отменяйте предыдущие таймеры.

Реализация немедленного режима

Ограничитель частоты с немедленным обновлением применяет первое значение сразу и игнорирует последующие до истечения интервала. Проверьте: если Date.now() - lastRunTime.current >= delay, обновите состояние и сохраните время. В противном случае пропустите обновление. Это обеспечивает мгновенный отклик на первое действие и период ожидания после него.

Сочетание немедленного и отложенного режимов

Наилучшее взаимодействие с пользователем часто сочетает оба режима: немедленно реагировать на первое событие (немедленный режим), а затем гарантировать применение итогового состояния после завершения интервала (отложенный режим). Благодаря этому пользователь сразу видит результат, а окончательное значение всегда применяется после остановки движения, что предотвращает устаревшее конечное состояние.

Использование useRef для ID таймера

Сохраняйте ID ожидающего таймера в useRef: const timeoutRef = useRef(null). Перед планированием нового таймера вызовите clearTimeout(timeoutRef.current), чтобы отменить существующий. Это предотвращает наложение нескольких таймеров, из-за которого в течение одного интервала ограничения частоты выполнялось бы несколько обновлений.

Очистка при размонтировании

Функция очистки useEffect должна вызывать clearTimeout(timeoutRef.current), чтобы отменить ожидающее отложенное обновление при размонтировании компонента. В противном случае ожидающий таймер сработает после размонтирования и попытается изменить состояние размонтированного компонента, что может привести к предупреждениям React.

Альтернатива: обратный вызов с ограничением частоты

Вместо хука, работающего со значением, можно создать хук ограничения частоты на основе useCallback: useThrottledCallback(fn, delay) возвращает версию функции с ограничением частоты. Это гибче, когда ограничить частоту нужно для вызова функции, например для сбора аналитики, а не для реактивного значения.

Проверка ограничения частоты с поддельными таймерами

В тестах Jest используйте jest.useFakeTimers(), чтобы управлять временем. Настройте ограничитель частоты с задержкой 1000 мс, выполните 10 быстрых изменений значения, затем продвиньте искусственное время на 500 мс и проверьте, что произошло только 1 или 2 обновления. Продвиньте время еще на 500 мс и убедитесь, что сработало отложенное обновление. Это позволяет надежно проверить поведение ограничителя частоты.

Ограничение частоты в модели React

React обрабатывает обновления состояния пакетами во время отрисовки. Ограничитель частоты, работающий с обновлениями состояния, хорошо вписывается в эту модель. Однако учтите, что в конкурентном режиме React 18 отрисовку можно прервать. Сама логика ограничения частоты, основанная на реальном времени через Date.now(), не зависит от планирования React.

Отложенный или немедленный режим ограничения частоты

На каком крае срабатывает ограничитель частоты с «отложенным» режимом?

Итоги урока: хук useThrottle

Ограничение частоты требует отслеживания времени последнего выполнения с помощью useRef. Хук может реализовывать немедленный режим, отложенный режим или оба режима. Всегда сохраняйте ID таймера в ссылке и отменяйте его в функции очистки. Для вариантов использования на основе функций предпочитайте шаблон useThrottledCallback. Для надежности проверяйте код с помощью поддельных таймеров.

Часто задаваемые вопросы

Урок «Создание пользовательского хука useThrottle» бесплатный?

Да — полный текст урока «Создание пользовательского хука useThrottle» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс React Academy, подпишись на CoddyKit PRO. Курс React Academy содержит 4 уроков всего.

Чему я научусь в уроке «Создание пользовательского хука useThrottle»?

Создайте хук useThrottle, ограничивающий частоту обновления значения во время быстрых событий, например прокрутки Ты практикуешь React Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать React Academy?

Предыдущий опыт не требуется. React Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Создание пользовательского хука useThrottle»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке React Academy?

Да. Каждый урок React Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Зачем нужны debounce и throttle в интерфейсах
  2. Создание пользовательского хука useDebounce
  3. Создание пользовательского хука useThrottle
  4. Практическое применение: поиск, прокрутка, изменение размера
← Назад к React Academy