Ryan94
Ryan94

Reputation: 331

React Native Countdown Timer causes Invariant Violation

As this stackoverflow answer says, I tried to create a countdown timer for my project like below.

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>
 )
}

However after adding setState into componentDidUpdate function, I stated to get below error,

Invariant Violation: Maximum update depth exceeded

Since I'm only trying to get state under componentDidMount if and only if time equals to 0, I don' understand why I get above error because that code only execute only once and after state set, timeinterval get clear as well.

So can someone explain please what I'm doing wrong here? Thank you.

Upvotes: 0

Views: 647

Answers (2)

Robbie Milejczak
Robbie Milejczak

Reputation: 5770

The issue is your componentDidUpdate logic:

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

When you call this.setState({hideTime: true}) your componentDidUpdate logic gets revisited and since this.state.timer will be 0 at that point as you have not restarted the timer (componentDidMount will only be called once after your initial render and not on update)

Not entirely sure what you are trying to accomplish and what you're working with but this change should help

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

so by setting hideTime:true and then checking against that value you can prevent the infinite setState loop. If that check doesn't work for what you're trying to accomplish then you'll have to use different logic but hopefully you get the idea.

Upvotes: 2

Sandip Nirmal
Sandip Nirmal

Reputation: 2459

Answer to your question is in description of error itself. it says:

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.

Which means you should not update state in componentDidUpdate hook.

If you just remove this.setState({hideTimer:true}) from componentDidUpdate(), this should work fine.

https://codesandbox.io/embed/l50586k4q

Upvotes: 0

Related Questions