如何在React输入框中接入Lodash的debounce防抖功能?
实现方案
你可以按照下方代码实现防抖请求+失焦清空输入的需求,核心要保证防抖函数引用稳定,同时处理失焦时的待执行请求取消逻辑:
完整代码示例
import { useState, useRef, useEffect } from 'react'; import TextField from '@mui/material/TextField'; // 防抖函数原生实现,支持取消待执行任务,也可以直接使用lodash的debounce const debounce = (func, delay) => { let timeoutId; const debounced = (...args) => { clearTimeout(timeoutId); timeoutId = setTimeout(() => func.apply(this, args), delay); }; debounced.cancel = () => clearTimeout(timeoutId); return debounced; }; export default function App() { const [inputValue, setInputValue] = useState(''); // 用useRef存储防抖函数,保证引用稳定不随渲染重置 const debouncedRequest = useRef( debounce(async (keyword) => { if (!keyword.trim()) return; // 替换为你的实际API请求逻辑 console.log('发起API请求,搜索参数:', keyword); // const res = await fetch(`/your/api/path?keyword=${encodeURIComponent(keyword)}`); }, 300) // 防抖延迟可根据业务需求调整,一般300-500ms适用于搜索场景 ).current; const handleChange = (e) => { const currentVal = e.target.value; setInputValue(currentVal); debouncedRequest(currentVal); }; const clearInput = () => { // 先取消待执行的防抖请求,避免失焦后触发无用请求 debouncedRequest.cancel(); // 清空输入值,自动恢复placeholder显示 setInputValue(''); }; // 组件卸载时取消待执行请求,避免内存泄漏 useEffect(() => { return () => debouncedRequest.cancel(); }, [debouncedRequest]); return ( <form> <TextField onChange={handleChange} onBlur={clearInput} value={inputValue} placeholder="Do an api request" /> </form> ); }
核心说明
- 如果你需要使用节流而非防抖,只需要将上述代码中的防抖函数替换为节流实现即可,其余逻辑完全兼容
- 如果项目已经引入lodash,可直接引入lodash的debounce使用,无需自定义实现
- 输入框失焦清空值后会自动显示占位符,无需额外处理placeholder属性
内容的提问来源于stack exchange,提问作者Peter Boomsma
相关产品推荐
相关产品推荐

