如何为React搜索组件的数据库查询请求添加防抖延迟?
实现搜索输入的防抖(延迟查询)
我做了一个带ID搜索框的网站,用户输入任意字符(字母、数字等)时,会在数据库里搜索包含该字符序列的对应ID。比如数据库里有"petya"、"paul"、"polina"、"pelageya"、"andrew"这些记录:
- 输入"p"时显示前四条
- 输入"pe"时显示"petya"和"pelageya"
- 输入"pet"时仅显示"petya"
目前遇到的问题是:用户输入过程中会持续向服务器发送请求,想添加0.5秒的延迟——等用户停止输入达半秒时,再向数据库发送查询请求。比如用户连续输入"p"、"pe"、"pet"的间隔都不超过半秒,就只发送最终的"pet"查询请求。
当前使用的React组件代码如下:
function Search() { const { filters, setFilters } = useContext(PageContext) const [input, setInput] = useState("") useEffect(() => { var tmpFilters = { ...filters } tmpFilters.search = input setFilters(tmpFilters) }, [input]) return ( <div> <CssTextField value={input} onChange={(e) => { setInput(e.target.value) }}/> </div> ) }
解决方案:用定时器实现防抖
修改代码,通过setTimeout和清理函数来实现延迟查询,只有用户停止输入0.5秒后才触发请求:
function Search() { const { filters, setFilters } = useContext(PageContext) const [input, setInput] = useState("") useEffect(() => { // 设置0.5秒后执行查询逻辑 const delayTimer = setTimeout(() => { const updatedFilters = { ...filters } updatedFilters.search = input setFilters(updatedFilters) }, 500) // 每次input变化时,清除上一次未执行的定时器 return () => clearTimeout(delayTimer) }, [input, filters]) return ( <div> <CssTextField value={input} onChange={(e) => { setInput(e.target.value) }}/> </div> ) }
关键逻辑说明:
- 每次
input变化时,启动一个0.5秒的定时器,定时器到期后才更新filters(触发查询) - 返回的清理函数会在
input再次变化或组件卸载时,清除之前的定时器。这样如果用户在0.5秒内继续输入,之前的定时器就会被取消,不会触发无效请求 - 把
filters加入依赖数组,避免闭包导致使用旧的filters值
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

