如何在React中实现函数防抖?onChange事件防抖不生效该如何解决?
问题原因
debounce函数执行后会返回一个新的防抖处理函数,你当前的写法每次触发输入事件时都会重新生成防抖函数,无法复用同一个定时器缓存,防抖逻辑自然不会生效- 输入框的
onChange回调中你直接执行了onChange(e.target.value),相当于没有把逻辑交给防抖函数控制,逻辑还是即时触发 - 函数组件每次渲染都会重新生成内部函数,防抖函数需要持久化存储,否则每次渲染都会重置定时器状态
修正方案
你可以用useCallback持久化防抖函数,调整后的完整代码如下:
import React, { useState, useCallback, useEffect } from 'react' import { debounce } from "lodash"; const Search = ({getQuery}) => { const [text, setText] = useState('') // 持久化防抖函数,仅在getQuery变更时重新生成 const debouncedGetQuery = useCallback( debounce((q) => getQuery(q), 3000), [getQuery] ) // 组件卸载时清除防抖定时器,避免内存泄漏 useEffect(() => { return () => { debouncedGetQuery.cancel() } }, [debouncedGetQuery]) const onChange = (e) => { const q = e.target.value // 输入框内容实时更新,不需要防抖 setText(q) // 搜索请求走防抖逻辑 debouncedGetQuery(q) } return ( <section className='search'> <form> <input type='text' className='form-control' placeholder='Search characters' value={text} onChange={onChange} autoFocus /> </form> </section> ) } export default Search
额外说明
如果你的需求是连输入框内容更新也做防抖,只要把setText也放到debounce的回调里即可,不过这种场景下输入框会有明显的输入延迟,不推荐这么做。
内容的提问来源于stack exchange,提问作者Darius
相关产品推荐
相关产品推荐

