useTimeoutExtended
Описание
Хук useTimeoutExtended предоставляет полностью контролируемый таймер с методами управления (start, restart, cancel) и состоянием (isPending, isDone).
Таймер никогда не запускается автоматически — его всегда нужно запускать вручную.
Если нужен простой автоматический одноразовый таймер, рекомендуется использовать хук useTimeout.
Сигнатура
ts
// Вариант 1: с дефолтной задержкой
function useTimeoutExtended(
callback: UseTimeoutExtendedCallback,
delayMs: number,
): UseTimeoutExtendedReturn;
// Вариант 2: без дефолтной задержки
function useTimeoutExtended(
callback: UseTimeoutExtendedCallback,
): UseTimeoutExtendedReturn<true>;Параметры
callback— функция, вызываемая после завершения таймера. Получает фактическое время выполнения (мс).delayMs(опционально) — дефолтная длительность таймера. Используется при запуске без указания override‑значения.
Возвращает
- Объект‑структуру, включающую:
- Методы:
start(overrideDelayMs?)— запускает или перезапускает таймер. Если передать аргумент, используется override‑длительность и она игнорирует последующие измененияdelayMs.restart(overrideDelayMs?)— алиасstartдля читаемости.cancel()— отменяет активный таймер.
- Состояние:
isPending— таймер активен.isDone— таймер завершён.
- Методы:
- Объект‑структуру, включающую:
Поведение
- Хук не запускает таймер автоматически.
- При вызове
start()илиrestart():- если передан
overrideDelayMs, используется эта длительность и будущие измененияdelayMsигнорируются; - если аргумент не передан, используется текущее значение
delayMsи при измененииdelayMsтаймер будет автоматически пересчитан, чтобы суммарная длительность соответствовала новому значению.
- если передан
cancel()сбрасывает состояние и отменяет выполнение колбэка.- При размонтировании компонента активный таймер автоматически очищается.
Примеры
1) С дефолтной задержкой
tsx
import { useTimeoutExtended } from '@webeach/react-hooks';
function Example() {
const { start, cancel, isPending, isDone } = useTimeoutExtended((elapsed) => {
console.log(`Прошло ${elapsed} мс`);
}, 1000);
return (
<div>
<button onClick={() => start()}>Старт (1с)</button>
<button onClick={() => start(2000)}>Старт с override (2с)</button>
<button onClick={cancel}>Отмена</button>
<p>
{isPending && 'Таймер активен...'}
{isDone && 'Готово!'}
</p>
</div>
);
}2) Без дефолтной задержки
tsx
import { useTimeoutExtended } from '@webeach/react-hooks';
function Example() {
const { start } = useTimeoutExtended((elapsed) => {
alert(`Таймер завершился за ${elapsed} мс`);
});
return <button onClick={() => start(500)}>Старт на 500 мс</button>;
}Когда использовать
- Нужен полный контроль над запуском, перезапуском и отменой таймера.
- Нужно учитывать изменение задержки «на лету» с перерасчётом оставшегося времени.
- Важно различать состояния
isPendingиisDone.
Когда не использовать
- Если нужен простой таймер «fire‑and‑forget» без ручного управления — используйте
useTimeout. - Если требуется периодическое выполнение — используйте
useLoop. - Если нужно запускать несколько таймеров одновременно, лучше написать менеджер или использовать пул.
Частые ошибки
- Ожидание, что таймер стартует автоматически — на самом деле нужно явно вызвать
start(). - Изменение
delayMsне влияет на активный таймер, если он был запущен сoverrideDelayMs. isDoneиisPendingобновляются только если они реально используются (ленивое обновление).
Типизация
- Экспортируемые типы
UseTimeoutExtendedCallback— функция:(actualTime: number) => void.UseTimeoutExtendedReturn<RequiredMsArg = false>— объект методов и состояния.