react事件回调中使用防抖失败的常见错误和正确使用方式
作者:学习两年半的前端练习生
这篇文章主要介绍了react事件回调中使用防抖失败的常见错误和正确使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
使用时常见的错误和原因
问题:直接把debounce(防抖函数)当回调函数用(体现在debounce内执行函数,而不是函数本身)
报错代码:func is not a function TypeError: func is not a function at eval (http://localhost:3005/static/js/bundle.js:306181:32)。
原因:debounce的基本用法是:
传入一个“函数”和等待时间,返回一个新的“防抖后函数”。你应该调用返回的这个新函数,而不是在debounce内直接执行原函数。
onChange={(debounce(changeDepartmentId("123"), 300))}
问题:直接把debounce(防抖函数)套在回调函数外面,但是debounce内的回调函数却没有执行任何内容。
错误代码和原因:对react中事件回调了解不够,导致防抖函数没有执行。
//这种的回调是把 debounce 函数作为属性传给子组件,而父中定义的changeDepartmentId只是单纯的函数 onChange={debounce(changeDepartmentId, 300)} // 这种的回调是把 changeDepartmentId 函数作为属性传递给子组件,当onChange事件触发,子组件内调用 changeDepartmentId 函数 onChange={changeDepartmentId} // 这种写法是直接在onChange事件中调用 changeDepartmentId 函数 onChange={(value)=>changeDepartmentId(value)}
问题:正确使用了防抖但是没有起到防抖效果,常见原因和错误代码:
这样每次调用 changeDepartmentId,都会重新创建一个新的 debounce 实例,而不是复用同一个防抖函数。
这样的话,防抖的定时器每次都是新的,根本起不到“上一次未到时间就清除本次”的效果,所以没有防抖。
changeDepartmentId={(value) => { debounce(setState(prev => ({ ...prev,id:value})), 300) }}
正确用法下的解决方案
在组件外部或 useCallback/useMemo 里只创建防抖函数,然后复用它。 (防止防抖函数重复创建)
//部门编号搜索联想,useCallback防止函数重新创建实例 const changeDepartmentId = useCallback( //正确防抖 debounce((value: string) => { //设置搜索值 setState(prev => ({ ...prev, searchData: { ...prev.searchData, departmentIdentifier: value } })) }, 300), [] ); //使用回调 changeDepartmentId={changeDepartmentId}
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。