如何调用setInterval上的按钮点击在React应用程序?



我试着写一个程序,当用户按开始时增加计数器当用户按下stop时停止递增

输出应该如下所示

然后应该是

XXX-0-XXX

XXX-1-XXX

XXX-2-XXX

进程应该在stop时停止。

代码(不能工作):

import React from 'react'
import './App.css'
function App() {
const [counter, setCounter] = React.useState(0)
const [intervalID, setIntervalID] = React.useState(null)
const increment = () => {
const nextCounter = counter + 1
setCounter(nextCounter)
}
const onClickStart = () => {
setIntervalID(setInterval(increment, 100))
}
const onClickStop = () => {
clearInterval(intervalID)
setIntervalID(null)
}
return (
<div className="App">
<label>XXX-{counter}-XXX</label>
<button onClick={onClickStart}>Start</button>
<button onClick={onClickStop}>Stop</button>
</div>
)
}
export default App

之后的问题

XXX-1-XXX

显示,然后一切停止。

我看了类似的问题,但没有发现setInterval是从一个按钮点击调用。看起来我不明白一些显而易见的事情。因此,任何帮助都是感激的。

更新:

我的问题在这里没有答案:

JavaScript On-click函数开始和停止间隔

这是一个类似的问题,但它没有回答我的问题。

我的问题的答案是由Dennis Kats写的,答案是固定增量函数:

const increment = () => setCounter(oldCounter => oldCounter + 1);

问题是,您的增量函数创建了counter变量的闭包,setInterval执行初始的increment函数,其中counter始终仍然为0,每次。结果,setInterval反复将计数器设置为1。如果你不熟悉React中的闭包,你可以在这里了解更多。

同时,为了修复你的代码,setCounter可以选择一个函数,从当前值(即使在状态更新之后)映射到下一个值应该是什么。这样,increment实际上不会关闭计数器状态,而是通过setCounter动态地接收它,因此它能够正确地增加该值。

下面是一个工作示例:

function App() {
const [counter, setCounter] = React.useState(0)
const [intervalID, setIntervalID] = React.useState(null)
// here is the primary change!!
// we simply tell setCounter to add 1 to the old counter value
const increment = () => setCounter(oldCounter => oldCounter + 1);
const onClickStart = () => {
if (intervalID === null) // small fix to prevent starting multiple intervals
setIntervalID(setInterval(increment, 100));
}
const onClickStop = () => {
clearInterval(intervalID);
setIntervalID(null);
}
return ( 
<div className="App">
<label>XXX-{counter}-XXX</label>
<button onClick={onClickStart}>Start</button>
<button onClick={onClickStop}>Stop</button>
</div>
)
}
ReactDOM.createRoot(document.getElementById("root")).render( < App / > );
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>
<div id="root"></div>

最新更新