useEffect清除定时器

新手上路,请多包涵

useRef保存值,用来清除定时器;但是在清除定时器时写的useEffect第二个参数传递问题导致无法清除,不传参数时可以清除,传递反而不能清除,请问为什么?
image.png


import React, { useState, useRef, useEffect } from 'react';

// useRef保存timer
export default function App(props) {
  const [count, setCount] = useState(0);
  const timerRef = useRef();
  console.log(timerRef)

  useEffect(() => {
    timerRef.current = setInterval(() => {
      if (count < 2) {
        setCount(count => count + 1);
      }
    }, 10);
    console.log(timerRef.current, '1 effect') // 2 "1 effect"
  }, []);

  useEffect(() => {
    console.log(timerRef.current, '2 effect'); // 2 "2 effect"
    if (count >= 2) {
      clearInterval(timerRef.current)
    }
  }) //为什么第二个参数传入[],反而不能清除定时器呢?
  // }, [])

  return (
    <div>
      <div>数值:{count}</div>
    </div>
  );
阅读 16.7k
2 个回答
✓ 已被采纳新手上路,请多包涵

执行1次, count不满足清除的条件,不能清除,需要传入[count],生效。感谢@jokester

感觉你回答的太简单了,我忍不住插个嘴。

useEffect 第二个参数是他的依赖值数组,可以根据依赖变动执行响应 effect。文档显示,有三种情况:

1. 不传

表示每轮组件渲染完成后执行,也就是渲染一次执行一次。有点像 componentDidUpdate

2. 传空数组 []

表示没有任何依赖,永远都只执行一次。有点像 componentDidMount

3. 传入一个依赖数组 [props.haha]

表示依赖发生变化,渲染后执行。还是像 componentDidUpdate 只是设置了门槛

所以想要清除定时器生效就要依赖 count,在变成大于 2 时执行;除此之外,我认为还要在组件卸载的时候执行,因为组件卸载可能先于 count >= 2。所以还要加一句:

  useEffect(() => {
    timerRef.current = setInterval(() => {
      if (count < 2) {
        setCount(count => count + 1);
      }
    }, 10);
    console.log(timerRef.current, '1 effect') // 2 "1 effect"
    return () => {
        timerRef.current && clearInterval(timerRef.current)
    }
  }, []);
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题