在reactjs中单击我的按钮时,如何停止两个计时器。
我注意到,当我的计时器运行时,我的整个组件每次都在重新呈现如何避免使用此部分。
users:{
$uid:{
Posts:{
$post_id: {...}
}
}
}
答案 0 :(得分:2)
最好的方法是添加一个代表state
工作的status
变量。即:“正在工作”,“已暂停”并进行切换。
此外,您需要从超时中取消订阅,以避免在组件卸载后状态更新。
下面是一个可以停止和恢复计时器的示例:
export default function App() {
const [counterSecond, setCounterSecond] = React.useState(0);
const [counter, setCounter] = React.useState(120);
const [time, setTime] = React.useState("");
const [status, setStatus] = React.useState("working");
React.useEffect(() => {
let secondCounterId;
let counterId;
if (status === "working") {
secondCounterId = setTimeout(
() => setCounterSecond(counterSecond + 1),
1000
);
counterId = setTimeout(() => setCounter(counter - 1), 1000);
}
return () => {
clearTimeout(counterId);
clearTimeout(secondCounterId);
};
}, [counterSecond, counter, status]);
const handletimer = () => {
setTime(counterSecond);
};
const stopTimers = () => {
setStatus("paused");
};
const resume = () => {
setStatus("working");
};
return (
<div className="App">
<div>Countdown: {counterSecond}</div>
<div>Countdown Reverse: {counter}</div>
<div>time: {time} </div>
<button onClick={handletimer}>Submit</button>
<button onClick={stopTimers}>Stop</button>
<button onClick={resume}>resume</button>
</div>
);
}
还有工作中的codesandbox
答案 1 :(得分:1)
您可以创建一个timerRunning
(布尔值)变量来检查计时器是否应在useEffect()
中运行,如下所示:
const [timerRunning, setTimerRunning] = React.useState(true);
React.useEffect(() => {
if (timerRunning) {
setTimeout(() => setCounterSecond(counterSecond + 1), 1000);
setTimeout(() => setCounter(counter - 1), 1000);
}
}, [counterSecond , counter, timerRunning]);
然后在timerRunning
中切换handletimer
:
const handletimer = () => {
setTimerRunning(false);
// ... other logic
};
答案 2 :(得分:0)
运行时间的原因是因为在每次渲染后都会调用useEffect(),因此需要时间。因此,要进行更正,可以设置为“时间”处于初始状态,然后执行这些功能,否则不进行设置。因此,在将渲染时间设置为新时间后,问题将得到解决。