1. 基本概念--是什么?
原理:一个 dom 事件被触发时,会设定一个延迟处理时间,在这个时间内再次触发该事件,则会重新设定一个延迟处理时间。
2. 需求描述--有啥用?
场景某个文本输入框中的值发生改变,需要发起网络数据请求。
问题当用户每次向文本输入框输入值时,都会发起网络请求。那么用户在输入值时,大量的发起网络请求,给服务端造成了一定程度上的压力。
3. 需求分析--分析问题!
我们需要一个工具函数(或者hooks),这个工具函数(或者hooks)需要有以下几个功能:
| 参数 | 含义 | 默认值 |
|---|---|---|
| value | 需要防抖的值 | - |
| wait | 时间周期,单位为毫秒 | 500 |
综上所述,梳理思路如下:
首先 声明一个函数(或hooks)useDebunce。此函数接受需要防抖的值和自定义时间周期。
其次 使用定时器完成之间模拟时间周期。当事件触发后,如果之前的定时器存在则清除该定时器;否则声明一个定时器。
最后 声明响应式数据 debunceValue,当定时器的回调函数执行时,将防抖的值赋值给声明的响应式数据并将其作为该函数(或hooks)的返回值。
4. 手动实现--独立自主!
// hooks 核心函数
function useDebunce(...props) {
let [value, wait = 500] = props
// 定时器
const timer = useRef(null)
// 防抖的值
const [debunceValue, setDebunceValue] = useState();
// 上一个周期还在,则清空上个周期
if (timer.current) {
clearInterval(timer.current)
}
// 开始新的周期
timer.current = setTimeout(() => {
setDebunceValue(value)
clearInterval(timer.current)
}, wait)
return debunceValue
}
// 测试
export default () => {
const [value, setValue] = useState();
const debouncedValue = useDebunce(value);
return <>
<input
type="text"
value={value}
onChange={(e) => {
setValue(e.target.value)
}} />
<p>输入框的值: {debouncedValue}</p>
</>
}