在 React 应用中,处理频繁变化的输入(如用户输入、滚动事件等)时,直接响应每次变化可能会导致性能问题。useDebounce
钩子提供了一种优雅的方式来延迟处理这些频繁的更新,只在一定时间内没有新的更新时才触发操作。这个自定义钩子不仅可以提高应用的性能,还能减少不必要的 API 调用或复杂计算。以下是如何实现和使用这个自定义钩子:
const useDebounce = (value, delay) => {
const [debouncedValue, setDebouncedValue] = React.useState(value);
React.useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(handler);
};
}, [value]);
return debouncedValue;
};
const Counter = () => {
const [value, setValue] = React.useState(0);
const lastValue = useDebounce(value, 500);
return (
<div>
<p>
Current: {value} - Debounced: {lastValue}
</p>
<button onClick={() => setValue(value + 1)}>Increment</button>
</div>
);
};
ReactDOM.createRoot(document.getElementById('root')).render(
<Counter />
);
这个技巧的关键点包括:
使用 useState
存储防抖后的值。使用 useEffect
监听原始值的变化,并设置一个延迟更新的定时器。在 effect 的清理函数中取消上一个未执行的定时器,确保只有最后一次更新生效。
使用这个钩子时,需要注意以下几点:
防抖值会延迟更新,因此它总是"滞后于"原始值。 延迟时间(delay)决定了防抖的"灵敏度"。 这个钩子特别适用于需要对频繁变化的输入做出响应的场景。
扩展应用:
实现一个防抖搜索输入:
const SearchComponent = () => {
const [searchTerm, setSearchTerm] = React.useState('');
const debouncedSearchTerm = useDebounce(searchTerm, 300);
React.useEffect(() => {
if (debouncedSearchTerm) {
// 执行搜索操作
performSearch(debouncedSearchTerm);
}
}, [debouncedSearchTerm]);
return (
<input
type="text"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
placeholder="Search..."
/>
);
};优化窗口调整事件处理: