import { useState, useEffect, useRef, useCallback } from 'react';
export function useDebounce(value, delay = 300) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const timer = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(timer);
};
}, [value, delay]);
return debouncedValue;
}
export function useDebouncedCallback(callback, delay = 300, deps = []) {
const timeoutRef = useRef(null);
const callbackRef = useRef(callback);
useEffect(() => {
callbackRef.current = callback;
}, [callback]);
const debouncedCallback = useCallback((...args) => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
timeoutRef.current = setTimeout(() => {
callbackRef.current(...args);
}, delay);
}, [delay, ...deps]);
useEffect(() => {
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
};
}, []);
return debouncedCallback;
}
export function useThrottle(value, interval = 300) {
const [throttledValue, setThrottledValue] = useState(value);
const lastUpdated = useRef(Date.now());
useEffect(() => {
const now = Date.now();
const timeSinceLastUpdate = now - lastUpdated.current;
if (timeSinceLastUpdate >= interval) {
lastUpdated.current = now;
setThrottledValue(value);
} else {
const timer = setTimeout(() => {
lastUpdated.current = Date.now();
setThrottledValue(value);
}, interval - timeSinceLastUpdate);
return () => clearTimeout(timer);
}
}, [value, interval]);
return throttledValue;
}