React Native Countdown Timer导致不变违规

时间:2018-10-16 17:39:38

标签: javascript react-native

正如this stackoverflow answer所说,我试图为我的项目创建一个倒数计时器,如下所示。

constructor(props: Object) {
  super(props);
  this.state ={ timer: 3,hideTimer:false}
}

componentDidMount(){
  this.interval = setInterval(
    () => this.setState({timer: --this.state.timer}),
    1000
  );
}

componentDidUpdate(){
  if(this.state.timer === 0){
    clearInterval(this.interval);
    this.setState({hideTimer:true})        
  }
}

render() { 
  return (
    <View style={{ flex: 1, justifyContent: 'center', }}>
      <Text> {this.state.timer} </Text>
    </View>
 )
}

但是,在将setState添加到componentDidUpdate函数中之后,我说要得到以下错误,

Invariant Violation: Maximum update depth exceeded

由于仅当时间等于0时,我才尝试获取componentDidMount下的状态,所以我不明白为什么会出现上述错误,因为该代码仅在状态设置后执行一次,timeinterval get也清除。

那么有人可以解释一下我在做什么错吗?谢谢。

2 个答案:

答案 0 :(得分:2)

问题是您的componentDidUpdate逻辑:

componentDidUpdate(){
  if(this.state.timer === 0){
    clearInterval(this.interval);
    this.setState({hideTimer:true})        
  }

当您调用this.setState({hideTime: true})时,将重新访问componentDidUpdate逻辑,因为此时this.state.timer将为0,因为您没有重新启动计时器(componentDidMount仅会被调用首次渲染后一次,而不更新)

不太确定您要完成什么以及正在使用什么,但是此更改应该有所帮助

componentDidUpdate(){
  if(this.state.timer === 0 && !this.state.hideTimer){
    clearInterval(this.interval);
    this.setState({hideTimer:true})        
  }

因此,通过设置hideTime:true,然后对照该值进行检查,可以防止无限的setState循环。如果该检查对您要完成的工作不起作用,则您必须使用其他逻辑,但希望您能理解。

答案 1 :(得分:0)

问题的答案在于错误本身的描述。它说:

Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

这意味着您不应该更新componentDidUpdate挂钩中的状态。

如果您只是从this.setState({hideTimer:true})中删除componentDidUpdate(),这应该可以正常工作。

https://codesandbox.io/embed/l50586k4q