【发布时间】:2021-01-12 17:53:14
【问题描述】:
我将分两步介绍我的问题,其中的代码块略有不同。
第 1 步:
下面我们有一个 React 应用程序,它每两秒渲染一次,因此导致浏览器打印 render 到控制台。如果用户按下任何键,渲染将停止,进而停止控制台打印。请暂时忽略注释掉的行。
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 步导致额外渲染的原因可能是什么。也许这很明显?
setIsPaused(isPaused) 如果我注释掉由 setInterval 运行的其他状态更改,则永远不会导致新的渲染,这让我更加困惑。
【问题讨论】:
标签: reactjs render setinterval use-state react-state