UJjwal
UJjwal

Reputation: 5

setInterval unusual behaviour

I am working on the following code. Here i used a setInterval function and supposed it to increase the value of age by 1 every 2 seconds. But it is increasing age value in unusual way. like.. 21 23 29 ....

What wrong with my code or concept.

class First extends React.Component {
    constructor() {
        super();
        this.state = {
            age: 21
        }
    }

    handleEvent = () => {
        let val = this.state.age
        val++
        this.setState({age: val})
    }

    render() {
        setInterval(this.handleEvent, 2000)
        return (
            <div>
                <button>{this.state.age}</button>
            </div>
        )
    }
}

Upvotes: 0

Views: 35

Answers (3)

sanderdrummer
sanderdrummer

Reputation: 131

Try using componentDidMount for your sideEffects Render gets called on each state update.

class First extends Component {
  constructor() {
    super();
    this.state = {
      age: 21
    };
  }

  componentDidMount() {
    setInterval(this.handleEvent, 2000);
  }

  handleEvent = () => {
    this.setState((state) => ({ age: state.age + 1 }));
  };

  render() {
    return (
      <div>
        <button>{this.state.age}</button>
      </div>
    );
  }
}

Upvotes: 0

0stone0
0stone0

Reputation: 44275

You'll need to make sure setInterval is only called once! The easiest way is to move it inside the constructor.

Also, instead off creating the temporary val variable, we can just use this.state.age + 1:

Example:

class First extends React.Component {
    constructor() {
        super();
        this.state = {
            age: 21
        }
        setInterval(this.handleEvent, 2000);
    }

    handleEvent = () => {
        this.setState({age: this.state.age + 1});
    }

    render() {
        return (
            <div>
                <button>{this.state.age}</button>
            </div>
        )
    }
}


ReactDOM.render(<First />, document.body);
<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>

Upvotes: 0

Viet
Viet

Reputation: 12807

You should put setInterval in componentDidMount and clear it in componentWillUnmount:

componentDidMount() {
  this.interval = setInterval(this.handleEvent, 2000)
}

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

Upvotes: 2

Related Questions