Javascript 在React中设置setState的setInterval
我在React组件中有一个使用Javascript 在React中设置setState的setInterval,javascript,reactjs,Javascript,Reactjs,我在React组件中有一个使用setInterval()的计时器,我不确定在使用状态方面启动和停止此间隔的最佳做法是什么。我在这方面遇到了一些异步问题 假设我的React组件中有一组链接,用于呈现和执行回调: let links = [10, 50, 100, 500, 1000].map((num) => { return( <Link key={num} onClick={(e) => this.switchNums(num)} to={`/somePath/$
setInterval()
的计时器,我不确定在使用状态方面启动和停止此间隔的最佳做法是什么。我在这方面遇到了一些异步问题
假设我的React组件中有一组链接,用于呈现和执行回调:
let links = [10, 50, 100, 500, 1000].map((num) => {
return(
<Link key={num} onClick={(e) => this.switchNums(num)} to={`/somePath/${num}`}>{num}</Link>
)
})
以下是startTimer()
,stopTimer()
和reset()
:
其中一个错误是,尽管startTimer()。我猜这与setState()
的异步性质有关。另一个bug(我认为是相关的)是,当我缓慢单击时,它只会每隔一次启动间隔
有人能解释一下吗?或者他们做了什么来规避异步问题,将setState
与setInterval
结合使用(设置状态可以返回承诺吗?),或者哪种生命周期方法最适合这种情况?我认为这里最大的缺陷是您使用state
来存储间隔。虽然从技术上讲是可能的,但我看不出你有什么理由真的想这么做
相反,只需对组件使用局部变量:
startTimer(){
if(!this.timerId){
this.timerId = setInterval(()=>{
//your function
}, 1000);
}
}
stopTimer(){
clearInterval(this.timerId);
}
因此,我认为您根本不需要在这里为计时器使用状态。你的帖子中还有一些与州相关的一般性问题,我将在下面尝试回答这些问题。请记住,它们与解决您的特定问题无关
他们用setState()
做了什么来规避异步问题?
设置状态后,可以使用回调执行代码。关于这一点,有一个很好的解释;它是这样说的:
第二个参数是一个可选的回调函数,它将在setState完成并重新呈现组件后执行
哪种生命周期方法最适合这种情况?
上述文件的同一部分继续:
通常,我们建议对此类逻辑使用componentDidUpdate()
如果函数中有多个setState
,并且希望在特定事件后执行特定代码,我认为可以使用回调。出于更一般的目的,请使用上述生命周期方法。使用React钩子useState
和useEffect
可以执行以下操作:
const[timer,setTimer]=useState(1);
useffect(()=>{
const timerId=setInterval(()=>setTimer(timer+1),1000);
return()=>clearInterval(timerId);
});
天哪,你可以把东西存储在组件本身中。。。非常感谢。我会试试的谢谢你!这很有效。这可能是另一个问题,但除了组件的状态或道具之外,还有哪些东西是组件的属性呢?(除方法外)默认为无。请记住,state
和props
实际上是this
对象的属性(您将它们键入为this.state
和this.props
)--您的this.timer
变量也是如此。状态
和道具
都应该只包含数据,如果更改这些数据,就会触发组件的重新呈现。换句话说,如果不是数据直接(或至少直接)影响组件的渲染输出,那么它不应该是状态
或道具的一部分
@chris感谢您添加设置状态(nextState,callback);在你的回答中。这节省了我很多时间
startTimer(){
if(!this.state.timerId){
let timerId = setInterval(()=>{
let timer = this.state.timer + 1
this.setState({
timer: timer,
timerId: timerId
})
}, 1000)
}
}
stopTimer(){
clearInterval(this.state.timerId)
this.setState({timerId:null})
}
reset(size){
this.setState({
gameOver: false,
counter: 0,
correct: 0,
numbers: this.getRandomNumbers(size),
timer: 0
}, this.startTimer())
}
startTimer(){
if(!this.timerId){
this.timerId = setInterval(()=>{
//your function
}, 1000);
}
}
stopTimer(){
clearInterval(this.timerId);
}
setState(nextState, callback);