我试着写一个程序,当用户按开始时增加计数器当用户按下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>