useTimeout
React hook for declarative setTimeout management with automatic cleanup and dynamic delay control. Perfect for React applications requiring timed actions with Next.js integration and TypeScript support.
Installation
npx shadcn@latest add https://www.shadcn.io/registry/use-timeout.json
npx shadcn@latest add https://www.shadcn.io/registry/use-timeout.json
pnpm dlx shadcn@latest add https://www.shadcn.io/registry/use-timeout.json
bunx shadcn@latest add https://www.shadcn.io/registry/use-timeout.json
Advanced Usage
Demonstrates timeout control with conditional execution - a bomb defusing game where you can pause/resume the timer.
Features
- Declarative timeout management with automatic cleanup and dependency tracking
- Dynamic delay control including pause/cancel functionality using null values
- Latest callback execution ensuring most recent function is always called
- Automatic memory management with proper cleanup on unmount and re-renders
- TypeScript support with comprehensive type definitions and IntelliSense
- Zero external dependencies with lightweight React-only implementation
Use Cases
This free open source React hook works well for:
- Auto-save functionality - Delay save operations and cancel on new changes
- Delayed notifications - Show/hide messages with automatic timeout
- Game mechanics - Implement timers, countdowns, and time-based actions
- Debounced actions - Delay API calls, search queries, and user inputs
- UI animations - Control timed animations and transitions in React apps
- Loading states - Implement timeout-based loading indicators and fallbacks
API Reference
useTimeout
Parameter | Type | Default | Description |
---|---|---|---|
callback | () => void | - | Function to execute after the delay |
delay | number | null | - | Delay in milliseconds, or null to cancel/pause |
Usage Patterns
Basic Timer
import { useTimeout } from '@repo/use-timeout';
import { useState } from 'react';
function Timer() {
const [hasElapsed, setHasElapsed] = useState(false);
useTimeout(() => {
setHasElapsed(true);
}, 3000);
return (
<div>
{hasElapsed ? 'Time is up!' : 'Timer is running...'}
</div>
);
}
Conditional Timeout
import { useTimeout } from '@repo/use-timeout';
import { useState } from 'react';
function ConditionalTimer() {
const [isActive, setIsActive] = useState(true);
const [message, setMessage] = useState('Waiting...');
// Pass null to pause/cancel the timeout
useTimeout(() => {
setMessage('Timeout executed!');
}, isActive ? 2000 : null);
return (
<div>
<p>{message}</p>
<button onClick={() => setIsActive(!isActive)}>
{isActive ? 'Pause' : 'Resume'} Timer
</button>
</div>
);
}
Dynamic Delay
import { useTimeout } from '@repo/use-timeout';
import { useState } from 'react';
function DynamicTimer() {
const [delay, setDelay] = useState(1000);
const [count, setCount] = useState(0);
useTimeout(() => {
setCount(c => c + 1);
}, delay);
return (
<div>
<p>Count: {count}</p>
<input
type="number"
value={delay}
onChange={(e) => setDelay(Number(e.target.value))}
placeholder="Delay in ms"
/>
</div>
);
}
API Reference
useTimeout(callback, delay)
- callback:
() => void
- The function to execute after the delay - delay:
number | null
- Delay in milliseconds, ornull
to cancel/pause
Returns: void
Parameters
- callback: The function that will be called after the specified delay
- delay:
number
- Execute callback after this many millisecondsnull
- Cancel/pause the timeout (useful for conditional execution)
Use Cases
Auto-save Feature
useTimeout(() => {
saveDocument();
}, hasUnsavedChanges ? 2000 : null);
Show/Hide Messages
useTimeout(() => {
setShowMessage(false);
}, showMessage ? 5000 : null);
Delayed API Calls
useTimeout(() => {
fetchData();
}, searchQuery ? 300 : null); // Debounce search
Game Mechanics
// Game timer that can be paused
useTimeout(() => {
endGame();
}, isGameActive ? timeRemaining : null);
Implementation Notes
- Automatic Cleanup: The timeout is automatically cleared when the component unmounts or when the delay changes
- Latest Callback: Uses
useRef
to ensure the most recent callback is always executed - Conditional Execution: Passing
null
as delay prevents the timeout from being set - Re-triggering: When delay changes, the previous timeout is cleared and a new one is set
- Performance: No memory leaks - timeouts are properly cleaned up
Common Patterns
One-time Delay
// Execute once after component mounts
useTimeout(() => {
console.log('Component loaded');
}, 1000);
Conditional Execution
// Only run timeout when condition is met
useTimeout(
() => performAction(),
shouldRun ? 2000 : null
);
Reset Timer
// Reset timer by changing delay
const [resetKey, setResetKey] = useState(0);
useTimeout(() => {
// This will re-trigger when resetKey changes
}, 3000);
// Reset the timer
const resetTimer = () => setResetKey(k => k + 1);
useTernaryDarkMode
React hook for managing ternary dark mode (system, dark, light) with local storage support and system preference detection.
useToggle
React hook for toggle state management with array return pattern similar to useState. Perfect for React applications requiring clean boolean toggling with Next.js integration and TypeScript support.