本人已参与「新人创作礼」活动,一起开启掘金创作之路
对于useMemo和useCallback这两个hook,在日常中个人很少使用,一般都是在需要创建一个闭包的时候才使用,因为react的函数组件在每一次更新状态的时候,都是重新创建,如果不使用useMemo或者useCallback来缓存闭包,会导致运行的效果跟预计的不合。
useCallback和usememo都是有缓存的作用,个人认为区别在于useMemo
返回的是函数运行的结果,useCallback
返回的是函数。
useCallback(fn, deps) 相当于 useMemo(() => fn, deps)
const kao=()=>{
let time=null
return ()=>{
if(time) return
time=setTimeout(()=>{
console.log(1)
time=null
},1000)
}
}
const memo=useMemo(kao,[src1])
const callback=useCallback(kao,[src1])
<button onClick={()=>{
console.log(memo)
console.log(callback)
}}>测试</button>
console.log(memo)打印的结果如下
() => {
if (time) return;
time = setTimeout(() => {
console.log(1);
time = null;
}, 1000);
}
console.log(callbacl)打印的结果如下
() => {
let time = null;
return () => {
if (time) return;
time = setTimeout(() => {
console.log(1);
time = null;
}, 1000);
};
}
由此可见useMemo
返回的是函数运行的结果,useCallback
返回的是函数,同时也证明了useCallback(fn, deps) 相当于 useMemo(() => fn, deps)
接下来,使用usememo来封装一个节流和防抖的hook
防抖(debounce): 将多次高频操作优化为只在最后一次执行,通常使用的场景是:用户连续输入,只需要在输入结束后做一次校验即可,比如input搜索,校验
const useDebounce=(val:any,time:any)=>{
const [value,setValue]=React.useState(val)
const deboun=React.useMemo(()=>{
let tim:any=null
return (e:any)=>{
if(tim) clearTimeout(tim)
tim=setTimeout(()=>{
setValue(e)
},time)
}
},[time])
return [value,deboun]//使用数组的是因为不需要定义死参数
}
使用
const Cs=()=>{
const [value,setValue]=useDebounce('',300)
return <input onChange={(e)=>setValue(e.target.value)}/>
}
节流(thorttle):每隔一段时间执行一次,也就是降低频率,将高频操作优化成低频操作。通常使用场景: 滚动条事件,窗口resize事件,通常每隔100-500ms执行一次
const useThrottle=(val:any,time:any)=>{
const [value,setValue]=React.useState(val)
const deboun=React.useMemo(()=>{
let tim:any=null
return (e:any)=>{
if(time) return
tim=setTimeout(()=>{
setValue(e)
time=null
},time)
}
},[time])
return [value,deboun]
}
使用
const Cs=()=>{
const [value,setValue]=useThrottle('',300)
return <input onChange={(e)=>setValue(e.target.value)}/>
}