从useEffect中使用debounce来了解部分react hooks

·  阅读 3013

从useEffect中使用debounce来了解部分react hooks

由于项目升级接触到react-hooks,工作中遇到了debounce使用不生效问题,为了解决这个问题查阅相关资料并深入了解下hooks,毕竟解决一个问题的最好方法是先了解它,话不多说,look code:

踩坑历程

debounce一般使用

import debounce from 'lodash/debounce'

debounce(()=>search(value), 500)
复制代码

测试发现这一套在useEffect里是行不通的,我们对它做以下处理

import debounce from 'lodash/debounce'



const [value, setValue] = useState('')
<!--搜索函数-->
const search = (value)=>{
    console.log(value)
    <!--调用接口-->
}

<!--防抖处理-->
<!--处理方案一-->
const debounceFn = useCallback(
  debounce(callback => {
    callback()
  }, 1000),
  []
)
<!--value值变化触发-->
useEffect(() => {
    debounceFn(()=>search(params))
}, [value])
复制代码

测试一下,发现一秒未操作触发search函数 => 成功

简单优化一下

<!-- 处理方案二 -->
    const debounceFn = function(delay){
        return useCallback(
          debounce(callback => {
            callback()
          }, delay),
          []
        )
    }
<!--调用方法-->
const debounceSearch = debounceFn(500)
debounceSearch(()=>search(params))

<!--或者直接在useEffect中实现debounce-->
<!--处理方案三-->
useEffect(() => {
    // debounceSearch(params)
let timer;
return (...args) => {
  clearTimeout(timer);
  timer = setTimeout(()=>handleParams(params), 500,...args);
}
复制代码

最后,封装自定义hooks (最佳解决方案)

<!--处理方案四 useEffect自定义hooks -->
import { useEffect } from 'react'
function useDebounce(fn, delay, dep=[]) {
   useEffect(()=>{
      let timer;
      timer = setTimeout(fn, delay);
      return ()=>clearTimeout(timer); // 这里用到useEffect清除的能力 类似于componentWillUnmount
   }, [...dep]
  )
}
export default useDebounce
// 调用
useDebounce(()=>search(value), 500, [value])

<!--处理方案五 useRef自定义hooks -->
import { useRef } from 'react'
function useDebounce(fn, delay) {
    const timer = useRef(null);
    return () => {
        clearTimeout(timer.current);
        timer.current = setTimeout(fn, delay);
    }
}
export default useDebounce
// 调用
const debounceSearch = useDebounce(() => handleParams(params), 500)
useEffect(()=>{debounceSearch()},[value]

复制代码

资料研究

涉及到知识点debounce useEffect useCallback

  • debounce
function debounce(fn, wait=1000){
    let timer;
    return () => {
        clearTimeout(timer);
        timer = setTimeout(fn, wait);
    } 
}
复制代码
  • useEffect
// useEffect替代了之前的`componentDidMount`和`componentDidUpdate`
useEffect(()=>{
    console.log('我执行了')
    window.addEventListener('scroll', ()=>{})
    return ()=>window.removeEventListener('scroll', ()=>{})  // return里的函数代表清除副作用,类似于之前在componentWillUnmount钩子里做的事情
}, [...dep]) // dep为监测state的数组,当所依赖state内容变化时触发组件更新useEffect钩子,若为空,每次进入或组件update时都会触发
复制代码
  • useRef
useRef()Hook不仅仅用于DOM引用。“ ref”对象是一个通用容器,其current属性是可变的,可以保存任何值,类似于类的实例属性
复制代码

初次发文,还请各位大佬多多担待,有用的到的还请手留余香,点个赞

分类:
前端
标签:
分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改