Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setTimeout() in componentDidMount() does not work [duplicate]

I am trying to change the state of a component every 5 seconds as below inside componentDidMount() hook

import React, { Component } from 'react';

export default class ToTest extends Component {

  constructor(props) {
    super(props);
    this.state = {
      test: false
    };
  }

  componentDidMount() {
    setTimeout(() => { this.setState({ test: !this.state.test }) }, 5000);
  }

  renderDiv() {
    if(this.state.test) {
      return (<div>test is true</div>)
    }
    else {
      return (<div>test is false</div>)
    }
  }
  render() {
    return (
      <div>{ this.renderDiv() }</div>
    );
  }
}

But it executes only once. It changes from false to true once and then nothing. What am I missing?

like image 383
sruthi Avatar asked Mar 14 '18 11:03

sruthi


People also ask

Can we use setTimeout in componentDidMount?

Using setTimeout in React Components We'll call setTimeout inside of the useEffect Hook, which is the equivalent of the componentDidMount lifecycle method in Class components. import React, { useEffect } from 'react'; const App = () => { useEffect(() => { const timer = setTimeout(() => { setCount('Timeout called!'

Why does componentDidMount run twice?

Adding a key prop to your React component may trigger componentDidMount to be called multiple times.

Why is setTimeout not working?

If you are requiring the setTimeout functions to execute on the dot, there can be some scenarios when this is not the case. Late timeouts or timeouts that execute inaccurately could be due the following issues: browser or OS is busy with other tasks.

How many times componentDidMount gets called?

2. How many times componentDidMount is called? React components call componentDidMount only once by default. You can run the component multiple times if you delete the component or change the props or state.


1 Answers

componentDidMount() is only executed once when the component mounts and you only schedule it once. You have to use setInterval() to schedule it periodically.

Also when you update the state based on the current state you should use a callback in setState() that takes the previous state as react may batch multiple calls to setState().

And don't forget to cancel the timer in componentWillUnmount():

import React, { Component } from 'react';

export default class ToTest extends Component {
    state = {
        test: false,
    };

    componentDidMount() {
        this.timer = setInterval(
            () => this.setState(prevState => ({ test: !prevState.test })),
            5000,
        );
    }

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

    // other methods ...
}
like image 139
trixn Avatar answered Nov 14 '22 20:11

trixn