UNPKG

shelving

Version:

Toolkit for using data in JavaScript.

43 lines (42 loc) 1.68 kB
import { useEffect, useRef, useState } from "react"; /** * Set a state using a "debounce" delay — this ensures that the state is only updated after the specified delay has passed since the last update. * - Useful for input fields where you want to wait until the user has stopped typing before performing an action (e.g., API call). */ export function useDebouncedState(initial, delay = 500) { const [state, setState] = useState(initial); const _internal = (useRef(undefined).current ??= { timeout: null, setDebouncedState(v) { if (_internal.timeout) clearTimeout(_internal.timeout); _internal.timeout = setTimeout(() => setState(v), delay); }, }); return [state, _internal.setDebouncedState]; } /** * Debounce a callback function — the callback will only be invoked after the specified delay has passed since the last call. * - Useful for triggering form submissions after the user has stopped typing. * - Automatically cleans up pending timeouts on unmount. */ export function useDebouncedCallback(callback, delay = 500) { const timeoutRef = useRef(null); const callbackRef = useRef(callback); // Keep callback ref up to date callbackRef.current = callback; // Cleanup on unmount useEffect(() => { return () => { if (timeoutRef.current) clearTimeout(timeoutRef.current); }; }, []); return () => { if (timeoutRef.current) clearTimeout(timeoutRef.current); if (callbackRef.current) { timeoutRef.current = setTimeout(() => callbackRef.current?.(), delay); } }; }