需求:当鼠标在某个 dom 标签上移动的时候,记录鼠标的普通移动次数和加了防抖处理后的移动次数
为方便调试,先准备一个简单的防抖函数(一个高阶函数):
import React, { useState, useEffect, useMemo, useCallback } from "react";
function debounce(func, delay = 1000) {
let timer;
function debounced(...args) {
debounced.cancel();
timer = setTimeout(() => {
func.apply(this, args);
}, delay);
}
debounced.cancel = function () {
if (timer !== undefined) {
clearTimeout(timer);
timer = undefined;
}
}
return debounced
}
function Example() {
const [count, setCount] = useState(0);
const [bounceCount, setBounceCount] = useState(0);
const debounceSetCount = React.useMemo(() => debounce(setBounceCount), []);
const handleMouseMove = () => {
setCount(count + 1);
debounceSetCount(bounceCount + 1);
};
return (
<div onMouseMove={handleMouseMove} >
<p>普通移动次数: {count}</p>
<p>防抖处理后移动次数: {bounceCount}</p>
</div>
)
}
export default Example;
利用useMemo的依赖传空数组,Example组件只会在首次渲染时,调用debounce生成debounceSetCount,且debounceSetCount被缓存住,之后不管state怎么改变,组件多次渲染,都不会执行debounce;当然真正实现防抖还是通过debounce,useMemo实现性能优化。