通用工具函数
实战坑一:节流函数失效
节流函数错误写法
const debounce = (func, wait ) => {
// 放在这里失效, 无法节流,猜测是因为react合成事件,会在调用成功后注销掉事件,导致泄漏为全局变量的timer失效
// 所以无法通过对timer来判断是否有重复定时事件了
let timer
const context = this
// 这里不能用箭头函数,箭头函数没有自己的this,当这里用箭头函数写法的时候,context其实就是当前组件export这个对象
// context无法成为debounce调用是的this
return function(...args){
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
func.apply(context, args);
}, wait);
};
};
export { debounce }
节流函数正确写法
- until.js
let timer ;
const debounce = (func, wait ) => {
const context = this
return function(...args){
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
func.apply(context, args);
}, wait);
};
};
export { debounce }
实战坑2:react合成事件调用异步函数报错如下:
Warning: This synthetic event is reused for performance reasons
错误产生原因?
react合成事件中,调用异步函数,就会出现这样的错误,比如如下代码
const handleClick = (value: any) => {
console.log(value)
}
<Search
className="workflow_search"
placeholder="搜索"
onChange={debounce(this.handleClick, 1000)} //报错,因为这里onChange对应的debounce是一个异步调用函数
/>
关于react合成事件(SyntheticEvent )
为了跨浏览器兼容性,react用合成事件替代原生事件(包含原生所有事件)
出于性能原因,在调用事件回调之后,合成事件对象将不再存在,因此我们无法访问其属性,即event.target上的所有属性失效
如何解决合成事件调用异步函数(debounce)
将我们需要的属性event.targe.value先保存下来,然后传递给异步函数
而不是在异步函数中直接去访问event.target.value(这里因为合成事件原因,event.target.value已经为空),所以异步函数直接去访问目标属性不行
- 使用方法
const handleClick = (value: any) => {
console.log(value) //1秒内重复调用多次,只有最后一次的调用会生效
}
<Search
className="workflow_search"
placeholder="搜索"
onChange={({ target: { value }}) => debounce(this.handleClick, 1000)(value)} //正确用法,先把需要的value值保存下来
//onChange={debounce(this.handleClick, 1000)} 错误用法
/>
合成事件参考文章:https://medium.com/trabe/react-syntheticevent-reuse-889cd52981b6