A comprehensive collection of 75+ React hooks for state and UI management including storage, events, browser APIs, and performance optimizations
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Performance optimization hooks including debouncing, throttling, intervals, timeouts, and callback optimization for efficient React applications.
Declarative intervals with start/stop/toggle controls and automatic cleanup.
/**
* Declarative interval with controls
* @param fn - Function to execute on interval
* @param interval - Interval duration in milliseconds
* @param options - Configuration for auto-invoke
* @returns Object with interval controls and state
*/
function useInterval(fn: () => void, interval: number, options?: UseIntervalOptions): UseIntervalReturnValue;
interface UseIntervalOptions {
autoInvoke?: boolean; // Start interval immediately (default: false)
}
interface UseIntervalReturnValue {
start: () => void;
stop: () => void;
toggle: () => void;
active: boolean;
}Usage Examples:
import { useInterval } from "@mantine/hooks";
function Timer() {
const [seconds, setSeconds] = useState(0);
const interval = useInterval(() => {
setSeconds(s => s + 1);
}, 1000);
return (
<div>
<p>Seconds: {seconds}</p>
<button onClick={interval.toggle}>
{interval.active ? 'Pause' : 'Start'}
</button>
<button onClick={() => setSeconds(0)}>Reset</button>
</div>
);
}
// Auto-start interval
function AutoTimer() {
const [count, setCount] = useState(0);
useInterval(() => {
setCount(c => c + 1);
}, 1000, { autoInvoke: true });
return <div>Count: {count}</div>;
}Declarative timeout with start/clear controls.
/**
* Declarative timeout with controls
* @param callback - Function to execute after delay
* @param delay - Delay in milliseconds
* @param options - Configuration for auto-invoke
* @returns Object with timeout controls
*/
function useTimeout(callback: () => void, delay: number, options?: UseTimeoutOptions): UseTimeoutReturnValue;
interface UseTimeoutOptions {
autoInvoke?: boolean; // Start timeout immediately (default: false)
}
interface UseTimeoutReturnValue {
start: () => void;
clear: () => void;
}Debounced callback with cancel/flush/pending methods and advanced options.
/**
* Debounced callback with advanced controls
* @param callback - Function to debounce
* @param delay - Debounce delay in milliseconds
* @param options - Debounce configuration
* @returns Debounced function with control methods
*/
function useDebouncedCallback<T extends (...args: any[]) => any>(
callback: T,
delay: number,
options?: UseDebouncedCallbackOptions
): UseDebouncedCallbackReturnValue<T>;
interface UseDebouncedCallbackOptions {
maxWait?: number; // Maximum time to wait before forcing execution
leading?: boolean; // Execute on leading edge
trailing?: boolean; // Execute on trailing edge (default: true)
}
type UseDebouncedCallbackReturnValue<T> = T & {
cancel: () => void;
flush: () => void;
pending: () => boolean;
};Usage Examples:
import { useDebouncedCallback } from "@mantine/hooks";
function SearchInput() {
const [query, setQuery] = useState('');
const handleSearch = useDebouncedCallback((searchQuery: string) => {
// API call
console.log('Searching for:', searchQuery);
}, 500, {
leading: false,
trailing: true
});
useEffect(() => {
if (query) {
handleSearch(query);
} else {
handleSearch.cancel(); // Cancel pending search
}
}, [query, handleSearch]);
return (
<div>
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search..."
/>
<button onClick={() => handleSearch.flush()}>
Search Now
</button>
<p>Pending: {handleSearch.pending() ? 'Yes' : 'No'}</p>
</div>
);
}State with debounced updates to reduce re-renders.
/**
* State with debounced updates
* @param defaultValue - Initial state value
* @param wait - Debounce delay in milliseconds
* @param options - Debounce configuration
* @returns Tuple of debounced value and setter
*/
function useDebouncedState<T>(defaultValue: T, wait: number, options?: UseDebouncedStateOptions): UseDebouncedStateReturnValue<T>;
interface UseDebouncedStateOptions {
leading?: boolean; // Update on leading edge
}
type UseDebouncedStateReturnValue<T> = [T, React.Dispatch<React.SetStateAction<T>>];Debounced value updates for derived state.
/**
* Debounced value updates
* @param value - Value to debounce
* @param wait - Debounce delay in milliseconds
* @param options - Debounce configuration
* @returns Tuple of debounced value and cancel function
*/
function useDebouncedValue<T>(value: T, wait: number, options?: UseDebouncedValueOptions): UseDebouncedValueReturnValue<T>;
interface UseDebouncedValueOptions {
leading?: boolean;
}
type UseDebouncedValueReturnValue<T> = [T, () => void];Usage Examples:
import { useDebouncedValue } from "@mantine/hooks";
function ExpensiveComponent({ searchQuery }: { searchQuery: string }) {
const [debouncedQuery, cancel] = useDebouncedValue(searchQuery, 300);
// Only re-compute when debounced value changes
const expensiveResults = useMemo(() => {
return performExpensiveSearch(debouncedQuery);
}, [debouncedQuery]);
return (
<div>
<p>Searching for: {debouncedQuery}</p>
<button onClick={cancel}>Cancel Search</button>
<Results data={expensiveResults} />
</div>
);
}Throttled callback execution to limit call frequency.
/**
* Throttled callback execution
* @param callback - Function to throttle
* @param wait - Throttle delay in milliseconds
* @returns Throttled function
*/
function useThrottledCallback<T extends (...args: any[]) => any>(
callback: T,
wait: number
): T;State with throttled updates to limit update frequency.
/**
* State with throttled updates
* @param defaultValue - Initial state value
* @param wait - Throttle delay in milliseconds
* @returns Tuple of throttled value and setter
*/
function useThrottledState<T>(defaultValue: T, wait: number): [T, React.Dispatch<React.SetStateAction<T>>];Throttled value updates for performance optimization.
/**
* Throttled value updates
* @param value - Value to throttle
* @param wait - Throttle delay in milliseconds
* @returns Throttled value
*/
function useThrottledValue<T>(value: T, wait: number): T;Usage Examples:
import { useThrottledValue, useThrottledCallback } from "@mantine/hooks";
function ScrollHandler() {
const [scrollY, setScrollY] = useState(0);
// Throttle scroll updates for performance
const throttledScrollY = useThrottledValue(scrollY, 100);
const handleScroll = useThrottledCallback(() => {
setScrollY(window.scrollY);
}, 16); // ~60fps
useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, [handleScroll]);
return <div>Scroll position: {throttledScrollY}</div>;
}import { useDebouncedCallback, useDebouncedValue } from "@mantine/hooks";
function OptimizedSearch() {
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);
const [loading, setLoading] = useState(false);
// Debounce the search function
const debouncedSearch = useDebouncedCallback(async (searchTerm: string) => {
if (!searchTerm.trim()) {
setResults([]);
return;
}
setLoading(true);
try {
const response = await searchAPI(searchTerm);
setResults(response.data);
} finally {
setLoading(false);
}
}, 300);
// Alternative: debounce the value
const [debouncedQuery] = useDebouncedValue(query, 300);
useEffect(() => {
debouncedSearch(query);
}, [query, debouncedSearch]);
return (
<div>
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search..."
/>
{loading && <div>Searching...</div>}
<SearchResults results={results} />
</div>
);
}import { useInterval, useTimeout } from "@mantine/hooks";
function AnimationController() {
const [progress, setProgress] = useState(0);
const [isPlaying, setIsPlaying] = useState(false);
const animation = useInterval(() => {
setProgress(p => {
if (p >= 100) {
animation.stop();
setIsPlaying(false);
return 100;
}
return p + 1;
});
}, 50);
const resetTimeout = useTimeout(() => {
setProgress(0);
}, 1000);
const startAnimation = () => {
setIsPlaying(true);
animation.start();
};
const resetAnimation = () => {
animation.stop();
setIsPlaying(false);
resetTimeout.start();
};
return (
<div>
<div style={{ width: `${progress}%`, height: '20px', background: 'blue' }} />
<button onClick={startAnimation} disabled={isPlaying}>
Start
</button>
<button onClick={resetAnimation}>
Reset
</button>
</div>
);
}