react hook如何清空定时器?

作者站长头像
站长
· 阅读数 12

react版本:16.6.0

事情是这样的。一开始,是父组件来维护输入框数据的,useeffect会监听输入框的变化,然后做出操作。

但是我不想每次操作太频繁,于是在子组件这里让输入框维护自己的数据,不再去用父组件的数据。

在子组件里,当输入框数据变化时,我会每隔一段时间给父组件传递输入框的数据,进而触发父组件的操作。

但现在问题是,我发现我无法清空子组件的定时器,这个该如何操作?

const FilterHeader = ({ handleInput}) => {
    // 防抖
   const timerId = useRef()
   const [val, setVal] = useState('')
   const onChange = (e) => {
      const value=e.target.value
      setVal(value)
      clearTimeout(timerId.current)
      timerId.current = setTimeout(() => {
         handleInput('name',value)
         clearTimeout(timerId.current)
      }, 600)
   }

   useEffect(()=>()=>{
      console.log(timerId)
      clearTimeout(timerId.current)
      console.log(timerId)  // 没有清掉
   },[])
    
    return    <Input
               type="text"
               size="small"
               name="name"
               placeholder="输入关键词搜素"
               onChange={onChange}
            />
}
回复
1个回答
avatar
test
2024-07-14

很欣慰地看到你在 useEffect 返回的内层函数里面清除定时器,而不是直接清除。至少说明你对于清除副作用的地方是有所耳闻的,但是 useEffect 设计成这样,而不是专门搞一个 useClearEffect 的钩子函数的原因是:

useEffect(function outer(){
  // 在这里产生副作用
  return function inner(){
    // 在这里清除副作用
  }
})

👆这里的 inner 只负责清除 outer 产生的副作用,如果让它清除别的地方产生的副作用就可能出 Bug 。

所以再审视一下你自己的写法,问题就显而易见了。要在 React 函数式组件中使用防抖/节流,最好是基于 react hooks 封装自己的防抖/节流 hook,参考: react-ahooks 源码分析之useDebounceFn和useDebounce

回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容