1.防抖 (Debounce):
// 1. 自定义 Hook 实现防抖
import { useState, useEffect } from 'react';
function useDebounce<T>(value: T, delay: number = 300): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value);
useEffect(() => {
// 设置定时器
const timer = setTimeout(() => {
setDebouncedValue(value);
}, delay);
// 清理函数
return () => {
clearTimeout(timer);
};
}, [value, delay]);
return debouncedValue;
}
// 2. 使用示例:搜索框
const SearchComponent = () => {
const [searchText, setSearchText] = useState('');
const debouncedText = useDebounce(searchText, 500);
// 只有在 debouncedText 变化时才调用 API
useEffect(() => {
if (debouncedText) {
// 发起搜索请求
searchAPI(debouncedText);
}
}, [debouncedText]);
return (
<input
value={searchText}
onChange={(e) => setSearchText(e.target.value)}
placeholder="输入搜索内容"
/>
);
};
2.节流 (Throttle):
// 1. 自定义 Hook 实现节流
import { useState, useEffect, useRef } from 'react';
function useThrottle<T>(value: T, delay: number = 300): T {
const [throttledValue, setThrottledValue] = useState<T>(value);
const lastExecuted = useRef<number>(Date.now());
useEffect(() => {
const handler = setTimeout(() => {
if (Date.now() - lastExecuted.current >= delay) {
setThrottledValue(value);
lastExecuted.current = Date.now();
}
}, delay);
return () => {
clearTimeout(handler);
};
}, [value, delay]);
return throttledValue;
}
// 2. 使用示例:滚动事件处理
const ScrollComponent = () => {
const [scrollPosition, setScrollPosition] = useState(0);
const throttledPosition = useThrottle(scrollPosition, 200);
useEffect(() => {
const handleScroll = () => {
setScrollPosition(window.scrollY);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
useEffect(() => {
console.log('throttled scroll position:', throttledPosition);
}, [throttledPosition]);
return (
<div style={{ height: '2000px' }}>
Scroll Position: {throttledPosition}
</div>
);
};
3.实际应用场景:
// 1. 实时搜索建议
const AutoComplete = () => {
const [inputValue, setInputValue] = useState('');
const debouncedValue = useDebounce(inputValue, 500);
const [suggestions, setSuggestions] = useState<string[]>([]);
useEffect(() => {
if (debouncedValue) {
// 获取搜索建议
fetchSuggestions(debouncedValue)
.then(data => setSuggestions(data));
} else {
setSuggestions([]);
}
}, [debouncedValue]);
return (
<div>
<input
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
placeholder="输入关键词"
/>
<ul>
{suggestions.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
</div>
);
};
// 2. 窗口大小调整处理
const ResponsiveComponent = () => {
const [windowSize, setWindowSize] = useState({
width: window.innerWidth,
height: window.innerHeight
});
const throttledSize = useThrottle(windowSize, 200);
useEffect(() => {
const handleResize = () => {
setWindowSize({
width: window.innerWidth,
height: window.innerHeight
});
};
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return (
<div>
Throttled Window Size: {throttledSize.width} x {throttledSize.height}
</div>
);
};
4.带回调的防抖函数:
// 1. 防抖 Hook 带回调
function useDebounceCallback<T extends (...args: any[]) => any>(
callback: T,
delay: number
): T {
const timeoutRef = useRef<NodeJS.Timeout>();
return useCallback(
(...args: Parameters<T>) => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
timeoutRef.current = setTimeout(() => {
callback(...args);
}, delay);
},
[callback, delay]
) as T;
}
// 2. 使用示例
const SearchForm = () => {
const handleSearch = useDebounceCallback((value: string) => {
// 执行搜索
console.log('Searching for:', value);
}, 500);
return (
<input
onChange={(e) => handleSearch(e.target.value)}
placeholder="搜索..."
/>
);
};
5.带状态的节流函数:
// 1. 节流 Hook 带状态
function useThrottleState<T>(
initialValue: T,
delay: number
): [T, (value: T) => void] {
const [value, setValue] = useState<T>(initialValue);
const lastExecuted = useRef<number>(Date.now());
const setThrottledValue = useCallback((newValue: T) => {
if (Date.now() - lastExecuted.current >= delay) {
setValue(newValue);
lastExecuted.current = Date.now();
}
}, [delay]);
return [value, setThrottledValue];
}
// 2. 使用示例
const ScrollTracker = () => {
const [scrollPos, setScrollPos] = useThrottleState(0, 200);
useEffect(() => {
const handleScroll = () => {
setScrollPos(window.scrollY);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, [setScrollPos]);
return <div>Scroll Position: {scrollPos}</div>;
};
关键点:
- 防抖:等待一段时间后才执行,如果期间又触发则重新计时
- 节流:在一定时间内只执行一次
- 使用 useRef 保存定时器或上次执行时间
- 使用 useEffect 清理定时器
- 使用 useCallback 优化性能
使用场景:
- 防抖:搜索框输入、表单验证、窗口大小调整
- 节流:滚动事件处理、频繁点击按钮、实时保存
这些实现可以有效优化性能,减少不必要的操作。
标签:防抖,return,Debounce,value,delay,window,Throttle,useEffect,const From: https://blog.csdn.net/m0_73574455/article/details/144654793