Utility Hooks
Timer, animation, and helper hooks for common Stream Deck patterns.
useInterval
Safe interval hook that auto-cleans on unmount. Pass null to pause.
function useInterval(callback: () => void, delayMs: number | null): IntervalControls;interface IntervalControls {
reset: () => void;
}function ClockKey() {
const [time, setTime] = useState(new Date());
useInterval(() => {
setTime(new Date());
}, 1000);
return (
<div style={{
width: '100%', height: '100%',
alignItems: 'center', justifyContent: 'center',
background: '#000',
}}>
<span style={{ color: 'white', fontSize: 22 }}>
{time.toLocaleTimeString()}
</span>
</div>
);
}Call reset() on the returned controls to restart the interval from zero.
useTimeout
Safe timeout hook that auto-cleans on unmount. Pass null to cancel.
function useTimeout(callback: () => void, delayMs: number | null): TimeoutControls;interface TimeoutControls {
cancel: () => void;
reset: () => void;
}usePrevious
Returns the previous value of a variable from the last render.
function usePrevious<T>(value: T): T | undefined;function MyKey() {
const [count, setCount] = useState(0);
const prev = usePrevious(count);
// prev is undefined on first render, then trails count by one render
}useTick
Calls the callback repeatedly with delta time using timer-driven ticks. Pass a number to set target FPS, true for 60fps, or false to pause.
function useTick(
callback: (deltaMs: number) => void,
fpsOrActive?: number | boolean,
): void;Default FPS is 60. The callback receives the elapsed milliseconds since the last tick.
function AnimatedKey() {
const [rotation, setRotation] = useState(0);
useTick((delta) => {
setRotation((r) => (r + delta * 0.1) % 360);
});
// ...
}Note on Animation Performance
The actual frame rate is capped by the render debounce (default 16ms = ~60fps theoretical max). In practice, rendering time limits real throughput to roughly 10-30fps depending on component complexity.
useAnimationFrame
Deprecated: Use
useTickinstead.
Legacy wrapper that calls useTick under the hood with 60fps when active.
function useAnimationFrame(callback: (deltaMs: number) => void, active?: boolean): void;