function hooks

104 阅读1分钟

setInterval 问题

import React, { useState, useEffect, useRef } from "react";
import ReactDOM from "react-dom";

function Counter() {
  let [count, setCount] = useState(0);

  useEffect(() => {
    console.log(333);
    let id = setInterval(() => {
      console.log(222);
      setCount(count + 1);
    }, 1000);
    return () => {
      console.log(1111);
      clearInterval(id);
    };
  });

  return <h1>{count}</h1>;
}

const rootElement = document.getElementById("root");

// Second interval to demonstrate the issue.
// Fast updates from it cause the Counter's
// interval to constantly reset and never fire.
// setInterval(() => {
//   ReactDOM.render(<Counter />, rootElement);
// }, 100);
ReactDOM.render(<Counter />, rootElement);

运行结果是正常的,通过打印可以看出,它是先清除setInterval再添加setInterval来执行的,这样如果时间设置的较大没什么问题,但是如果设置时间比较小的话,还没有等到setInterval执行的时候,就已经被清除了

setInterval(() => {
  ReactDOM.render(<Counter />, rootElement);
}, 100);

可以看到一直没有得到执行就会被清除

image.png
这是因为每次render,都会执行useEffect,但是如果这样的代码的话

import React, { useState, useEffect, useRef } from "react";
import ReactDOM from "react-dom";

function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    let id = setInterval(() => {
      setCount(count + 1);
    }, 1000);
    return () => {
      console.log(1234);
      clearInterval(id);
    };
  }, []);

  return <h1>{count}</h1>;
}

const rootElement = document.getElementById("root");
ReactDOM.render(<Counter />, rootElement);

可以看到它会只执行一次,因为setCount只是取得了第一次传入的count,也就是0,所以数字就一直为1,但是循环还是在执行

image.png
可以参考如下链接进行使用setInterval overreacted.io/making-seti…