👁️
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

enhance debounce

+34 -7
+5 -2
.claude/HOOKS.md
··· 100 100 101 101 **Location**: `src/lib/useDebounce.ts` 102 102 103 - Standard debounce hook. Value updates are delayed by specified milliseconds. 103 + Debounce hook with flush capability. Value updates are delayed by specified milliseconds. 104 104 105 105 ```typescript 106 106 const [search, setSearch] = useState(""); 107 - const debouncedSearch = useDebounce(search, 300); 107 + const { value: debouncedSearch, flush, isPending } = useDebounce(search, 300); 108 + 109 + // flush() immediately updates to current value (useful for beforeunload) 110 + // isPending is true when there's a pending debounced update 108 111 ``` 109 112 110 113 ## useCommonTags
+29 -5
src/lib/useDebounce.ts
··· 1 - import { useEffect, useState } from "react"; 1 + import { useCallback, useEffect, useRef, useState } from "react"; 2 + 3 + export interface UseDebounceResult<T> { 4 + value: T; 5 + flush: () => T; 6 + isPending: boolean; 7 + } 2 8 3 - export function useDebounce<T>(value: T, delay: number): T { 9 + export function useDebounce<T>(value: T, delay: number): UseDebounceResult<T> { 4 10 const [debouncedValue, setDebouncedValue] = useState<T>(value); 11 + const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null); 12 + const latestValueRef = useRef(value); 13 + 14 + latestValueRef.current = value; 15 + 16 + const isPending = value !== debouncedValue; 17 + 18 + const flush = useCallback(() => { 19 + if (timeoutRef.current) { 20 + clearTimeout(timeoutRef.current); 21 + timeoutRef.current = null; 22 + } 23 + setDebouncedValue(latestValueRef.current); 24 + return latestValueRef.current; 25 + }, []); 5 26 6 27 useEffect(() => { 7 - const timer = setTimeout(() => { 28 + timeoutRef.current = setTimeout(() => { 8 29 setDebouncedValue(value); 30 + timeoutRef.current = null; 9 31 }, delay); 10 32 11 33 return () => { 12 - clearTimeout(timer); 34 + if (timeoutRef.current) { 35 + clearTimeout(timeoutRef.current); 36 + } 13 37 }; 14 38 }, [value, delay]); 15 39 16 - return debouncedValue; 40 + return { value: debouncedValue, flush, isPending }; 17 41 }