我将分两步介绍我的问题,两者的代码块略有不同。
步骤1:
下面我们有一个 React 应用程序,它每两秒渲染一次,因此导致浏览器将渲染打印到控制台。如果用户按下任意键,渲染将停止,从而停止控制台打印。请暂时忽略注释掉的行。
import { useState, useEffect, useRef } from 'react';
function App() {
  const [number, setUpdate] = useState(0);
  const [isPaused, setIsPaused] = useState(false);
  const intervalRef = useRef(undefined);
  useEffect(() => {
    intervalRef.current = setInterval(() => setUpdate(prevNumber => ++prevNumber), 2000);
    window.addEventListener('keydown', handleKeyDown);
  }, []);
  const handleKeyDown = () => {
    clearInterval(intervalRef.current);
    console.log('console log here');
    // setIsPaused(isPaused);
  };
  console.log('render');
  return null;
};
export default App;
上面发生的事情是,我让组件渲染了五次,然后我按下了一个键来停止组件渲染。
第2步:
在第 2 步中,我们有完全相同的应用程序,只是没有注释掉handleKeyDown 中设置的状态。
  const handleKeyDown = () => {
    clearInterval(intervalRef.current);
    console.log('console log here');
    // This is no longer commented out. Why does it cause a new render?
    setIsPaused(isPaused);
  };
这是应用程序的屏幕截图,其中包含在步骤 2 中进行的代码更改:

同样,在我按下一个键后,我让组件渲染了五次。但是现在有一个额外的渲染,即使状态不应该改变(因为状态实际上并没有改变,因为我们设置了与状态中已经存在的值相同的值)setIsPaused(isPaused)。
我很难理解在第 2 步导致额外渲染的原因可能是什么。也许这很明显?
如果我注释掉由 setInterval 运行的其他状态更改,则setIsPaused(isPaused)永远不会导致新的渲染,这让我更加困惑。
