0

我是 React 的初学者,遇到了一些问题。 当与特定渲染关联的 setInterval 被清除时?



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 () => clearInterval(id);
  },[]);

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

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

2 回答 2

1

它将在组件卸载事件中被清除:

useEffect(() => {
    let id = setInterval(() => {
      setCount(count + 1);
    }, 1000);
    return () => clearInterval(id); // <-- get called on component unmount
  },[]); // <--- get called once component mounted/rendered first time

有关更多详细信息:请阅读

React 究竟何时清理效果?

React 在组件卸载时执行清理。然而,正如我们之前所了解的,效果会为每次渲染运行,而不仅仅是一次。这就是为什么 React 还会在下次运行效果之前清理上一次渲染中的效果。

于 2020-05-21T11:34:31.740 回答
0

I think your actual problem is that the timer only updates once, right? Well thats because you lied to React about your dependencies, your effect uses count, add that as an dependency:

 useEffect(() => {
   let id = setInterval(() => {
     setCount(count + 1); // here you use count
   }, 1000);
   return () => clearInterval(id);
 }, [count]); // here you have to tell react about your dependencies

Now the function returned from the effect will be called whenever count changes, or when the component unmounts. So you could actually write your code as:

 useEffect(() => {
   let id = setTimeout(() => {
     setCount(count + 1);
   }, 1000);
   return () => clearTimeout(id);
 }, [count]);

This basically does: Whenever 'count' changes, shedule a timer to change 'count' again in 1 second.

However, using an interval that runs as long as the component is mounted would work too, but for that to work we need to (1) remove all dependencies (count) and (2) get the latest count somehow. Fortunately the state setter also takes a callback:

 useEffect(() => {
   let id = setInterval(() => setCount(count => count + 1), 1000);
   return () => clearInterval(id);
 }, []); // we don't lie anymore
于 2020-05-21T11:42:29.320 回答