为什么我不能停止反应功能组件的间隔

why I can't stop interval in react functional component

在我的代码中,我遇到了一些间隔问题。我有这样的情况

import { useState } from 'react';

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

  function handleClick() {
    const timer = setInterval(() => {
      if (count >= 10) {
        clearInterval(timer);
      } else {
        setCount((prevCount) => prevCount + 1);
      }
    }, 1000);
  }

  return (
    <>
      <button onClick={handleClick}>start</button>
      <p>{count}</p>
    </>
  );
}

export default App;

我想做的是在用户单击按钮时开始一个间隔,并在计数器达到 10 时停止它,但它永远不会停止,调试器说 setInterval 内的计数始终为 0。有人知道吗问题是什么?我还发现如果我像这样将组件重写为 class 组件

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }

  handleClick() {
    let myInterval = setInterval(() => {
      if (this.state.count >= 10) {
        clearInterval(myInterval);
      } else {
        this.setState((prevState) => ({
          count: prevState.count + 1,
        }));
      }
    }, 1000);
  }

  render() {
    return (
      <>
        <button onClick={this.handleClick.bind(this)}>start</button>
        <p>{this.state.count}</p>
      </>
    );
  }
}

它完美运行。
我不知道发生了什么,我花了将近一天的时间来弄清楚。
那么有人知道为什么 class 组件有效而 functional 组件无效吗?

提前致谢

你是seeing a stale count in the setInterval callback function since it captures the value at the time you're starting the timer

您可以使用“ref boxing”模式对状态原子的最新值进行可读引用:

import {useState, useRef} from 'react';

function App() {
  const [count, setCount] = useState(0);
  const countRef = useRef(null);
  countRef.current = count;  // Update the boxed value on render

  function handleClick() {
    const timer = setInterval(() => {
      if (countRef.current >= 10) {  // Read the boxed value
        clearInterval(timer);
      } else {
        setCount((prevCount) => prevCount + 1);
      }
    }, 1000);
  }

  return (
    <>
      <button onClick={handleClick}>start</button>
      <p>{count}</p>
    </>
  );
}

请注意,您目前没有正确清理卸载时的计时器,导致 React 在您卸载应用程序时向您发出警告。您的 class 组件也是如此。