useDebounce hook
A small generic hook for debouncing a fast-changing value — search inputs, resize handlers, anything you don't want firing on every keystroke.
The one hook I copy into nearly every project. Debounces a value so downstream effects (a search request, a save-to-localStorage call) only fire once the value has settled.
import { useEffect, useState } from "react";
export function useDebounce<T>(value: T, delayMs = 300): T {
const [debounced, setDebounced] = useState(value);
useEffect(() => {
const timeout = setTimeout(() => setDebounced(value), delayMs);
return () => clearTimeout(timeout);
}, [value, delayMs]);
return debounced;
}Usage #
function SearchInput() {
const [query, setQuery] = useState("");
const debouncedQuery = useDebounce(query, 300);
useEffect(() => {
if (debouncedQuery) runSearch(debouncedQuery);
}, [debouncedQuery]);
return <input value={query} onChange={(e) => setQuery(e.target.value)} />;
}The cleanup function matters here — without clearTimeout on unmount/re-run, a stale timeout from a previous keystroke can still fire and overwrite a newer value.
Related content
nvim-log-insert: A Neovim Plugin That Writes Your console.log Statements For You
A tiny Lua plugin that inserts a detailed console.log — file, line number, function, and variable name — with a single leader keymap.
Auth Context for Next.js (Cookie-Based Sessions)
A React context wrapping an API — login, logout, signup, and password reset — that keeps the client in sync with an httpOnly session cookie by revalidating on mount.
Clonify.io: Turning a Slow WordPress Marketplace into a High-Performance Next.js SaaS Platform
Rebuilding a digital-products marketplace from WordPress to Next.js and Payload CMS, with a custom JSON caching layer and secure, subscription-aware asset delivery.