javascript - 我找不到在 React 中暂停倒数计时器的方法(清除间隔似乎不起作用)
问题描述
我正试图弄脏我的手来建造一个番茄钟。我现在正试图暂停计时器,但我很难做到这一点。这是主 App 组件中的构造函数:
this.state ={
breakValue: 5,
sessionValue: 25,
time: 25*60*1000,
isRunning: false
}
现在,这个功能正在滴答作响:
countDown = (timeLeft ) =>{
this.setState({
time : timeLeft-1000,
})
我已经通过道具将此功能传递给控件组件:
countDown={this.countDown}
在 Controls 组件中,我已经像这样处理了该功能:
handleStart = () =>{
this.props.countDown(this.props.time);
}
我为 SetInterval 做了一个单独的函数:
interval = () =>{
setInterval(this.handleStart,1000)
}
最后,我将最终功能附加到 onClick 按钮:
handleSetInterval= () =>{
this.interval();
}
现在计时器正在滴答作响,倒计时正在工作。但是如何随时暂停这个计数器呢?我有另一个带有暂停功能的按钮,我尝试用 clearInterval 编写一个函数,但它不起作用。我应该使用布尔逻辑来启动/停止,还是可以处理 Main App 组件内的 clearInterval?我完全迷路了。谢谢你们的任何回答。
解决方案
请记住,这不会是一个超级准确的计时器,因为 setIntreval 进入队列,因此它的回调不会在 1000 毫秒时立即调用(这只是意味着它将每 1000 毫秒排队一次)
工作片段(根据您的规范,请查看第二个示例以获得更好的实践):
class Controls extends React.Component{
state={
myInterval : null
}
startTimer = () => {
this.setState({myInterval : setInterval(this.props.countDown,1000)})
}
stopTimer = () => {
clearInterval(this.state.myInterval)
}
render(){
return(
<div>
<button onClick={this.startTimer}>Start</button>
<button onClick={this.stopTimer}>Stop</button>
{this.props.time}
</div>
)
}
}
class App extends React.Component{
state ={
time: 25*60*1000
}
countDown = () => {
this.setState({
time : this.state.time-1000,
})
}
render(){
return <Controls time={this.state.time} countDown={this.countDown}/>
}
}
ReactDOM.render(
<App />,
document.getElementById("react")
);
<div id='react'></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
更好/最佳实践是将与计数器相关的所有内容移动到您的计数器组件中
如果您需要在应用程序的其他地方访问 this.state.time ,请考虑使用 useContext 或 Redux (根据 React 团队对频繁更改的状态的应用程序级别管理尝试使用 Redux 而不是 useContext ,这里就是这种情况)。
应用程序组件级别的 setState() 可能会在每次更新时重新渲染应用程序中的所有内容(在这种情况下大约每 1000 毫秒)
更好的例子:
class Controls extends React.Component{
state={
myInterval : null,
time: 25*60*1000
}
countDown = () => {
this.setState({
time : this.state.time-1000,
})
}
startTimer = () => {
this.setState({myInterval : setInterval(this.countDown,1000)})
}
stopTimer = () => {
clearInterval(this.state.myInterval)
}
render(){
return(
<div>
<button onClick={this.startTimer}>Start</button>
<button onClick={this.stopTimer}>Stop</button>
{this.state.time}
</div>
)
}
}
class App extends React.Component{
render(){
return <Controls/>
}
}
ReactDOM.render(
<App />,
document.getElementById("react")
);
<div id='react'></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
推荐阅读
- python - Cant Pickle 记忆类实例
- vmware-clarity - 如何为图标设置动画?
- swagger - 多级鉴别器 OpenAPI
- three.js - 如何从 threejs 调用 BufferGeometryUtils?
- jsf - JSF 在命令按钮操作后重新加载 ViewParam
- wpf - 如何在 ItemContainerStyle 的样式设置器中绑定到特定的 Item 属性?
- javascript - React:如何从另一个组件调用它自己的渲染组件函数?
- unity3d - 如何在 Unity 中为碰撞添加反作用力?
- angular - 来自 json 数据的未定义响应
- javascript - Firebase 函数日志为空