0

I am incrementing a counter by setState() of React using a setInterval method. But for every intervals the application is updating multiple times.

import React, { Component } from 'react';

export default class Arrival extends Component {
state = {
    count: 0,
    limitTo: 6
  }
  render() {
    try {
      setInterval(() => {
        this.setState({
          limitTo: this.state.limitTo + 6
        })
        console.log(this.state)
      }, 5000);
    } catch(err) {
      console.log(err)
    }
  return()
}
}

In the first 5 seconds, the state is getting updated once.

In the next 5 seconds, the state is getting updated 2 times.

In the next 5 seconds, the state is getting updated 4 times. and so on...

I want the state to only get updated once every 5 seconds.

1
  • 1
    move setInterval() to componentDidMount() Commented Oct 22, 2019 at 8:07

2 Answers 2

1

when the state update, the component will be also updated and re-render, hence the setInterval should not be inside render method. You can do this instead:

class Arrival extends Component {
  state = {
    count: 0,
    limitTo: 6
  };

  interval = 0;

  componentDidMount() {
    try {
      this.interval = setInterval(() => {
        this.setState({
          limitTo: this.state.limitTo + 6
        });
        console.log(this.state);
      }, 5000);
    } catch (err) {
      console.log(err);
    }
  }

  componentWillUnmount() {
    clearInterval(this.interval);
  }

  render() {
    return <div />;
  }
}

Edit busy-flower-wj0x5

Note: reminded by @FrankerZ, you should also clean up the interval when the component unmounts, otherwise the clock will keep ticking ;)

Sign up to request clarification or add additional context in comments.

1 Comment

You should include cleanup code if the component unmounts
1

setInterval() is called in render() method. This means that:

  1. It will be set off the first time it is rendered. Timers ticking: 1.
  2. After 5 seconds, it will fire and change the state. It means the component will need to rerender.
  3. Rendering starts another timer, since setInterval() is called in render() method. Timers ticking: 2.
  4. Another 5 seconds pass. First timer ticks again, which causes component to rerender due to state change. Another timer is set off. Timers ticking: 3.
  5. Second timer ticks for the first time. Another rerender happens and causes a 4th timer to be started. Timers ticking: 4.
  6. Ad infinitum

To solve this, move setInterval to componentDidMount() as recommended by another answer to ensure the timer is started once only, not on each render.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.