在有查询功能的项目中,只要输入框值的改变,请求出来的数据都会不同。
而对于即时查询功能,也就是一旦在输入框中值,数据即时请求且即时展示的项目,我们往往在输入几个关键字的时候触发多次请求.
这种即时查询系统,在react项目中一般都是使用useEffect对输入框的值的改变进行处理。
例子:
在输入物料管理系统这六个字的时候,我们就发送了三次请求,这对整个系统的稳定是不利的。
在这里我们使用debounnce解决这个问题。
在util工具函数中,我们这样定义
export const useDebounce=(value,delay)=>{
const [debouncedValue,setDebouncedValue]=useState(value);
useEffect(()=>{
const timeout=setTimeout(()=>{
setDebouncedValue(value)
},delay)
return ()=>clearTimeout(timeout);
},[value,delay])
return debouncedValue
}
解释:在React中useState等hook只能存在于两个地方,一是组件中,二是hook中,所以我们不能把Debounce写成一个简单的函数,加上use前缀,让编译系统认为这个东西是个hook,这样内部的hook才能正常使用。
在这个函数里面有两个参数:value与delay。
value是输入框的值,delay是我们确定的发送请求的可控间隔。
在useDebounce中使用useEffect对value和delay的改变进行操作。
一旦这次传入的value或者delay与上一次不同,就会触发一个delay长的定时器,定时器结束,就将debouncedValue的值改成这次传入的值。
可是如果在这delay时间内,在定时器未结束时,再次触发useDebounce传入两个又不同的参数,那么通过return ()=>clearTimeout(timeout);最新的一次传参就可以结束掉上一次那个没有进行完的定时器,实现完美覆盖。
最后我们每次传出的debouncecValue值都是这样代替了输入框的值value。
这样,我们在输入框的文件中就可以这样写:
const debouncedParam = useDebounce(param, 2000);
//param是输入框的值
useEffect(() => {
fetch(
`${apiUrl}/projects?${qs.stringify(cleanObject(debouncedParam))}`
).then(async (response) => {
if (response.ok) {
setList(await response.json());
}
});
}, [debouncedParam]);
//让这个数据随着debouncedParam的改变而改变
这就还是hook的独特之处,作为一个类函数的形式存在,却能够通过内部hook对每一次参数的改变进行处理,wudi。。。