react hook如何清空定时器?

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}
            />
}
阅读 3.7k
3 个回答

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

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

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

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

新手上路,请多包涵

看一下是否是每次都创建了新的子组件,因为我看你这个子组件有一个prop,而且是一个方法,建议在父组件中对这个handleInput方法使用useCallback方法进行包装,同时对FilterHeader 这个子组件使用useMemo进行缓存

你log的这个定时器id肯定是存在的 即使你清除了定时器。。 你要看定时器回调有没有触发

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题