Skip to main content

useScheduledTimer

import { useScheduledTimer } from '@crup/react-timer-hook/schedules';

useScheduledTimer() includes the lifecycle API from useTimer() plus schedule callbacks and optional diagnostics. It lives in a subpath so the root import stays small for clocks, stopwatches, and countdowns that do not need polling.

type UseScheduledTimerOptions = UseTimerOptions & {
schedules?: TimerSchedule[];
diagnostics?: TimerDiagnostics;
};

Schedules run while active and default to overlap: 'skip'. onError comes from UseTimerOptions and receives sync throws or async rejections from onEnd. It is also the fallback for schedule callback errors when a schedule does not define its own onError.

const timer = useScheduledTimer({
autoStart: true,
schedules: [
{
id: 'poll',
everyMs: 5000,
overlap: 'skip',
callback: async (snapshot, controls, context) => {
console.log(context.overdueCount);
},
onError: error => reportPollError(error),
},
],
});

The third callback argument contains scheduledAt, firedAt, nextRunAt, overdueCount, and effectiveEveryMs.

When the schedule cadence changes, the active scheduler recalculates the next timeout after the render commits. Changing only the callback keeps the current cadence and uses the latest callback on the next run.