Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJS: setTimeout() not working?

People also ask

How do I use setTimeout in Reactjs?

How to use setTimeout in React. The setTimeout function accepts two arguments: the first is the callback function that we want to execute, and the second specifies the timeout in milliseconds before the function will be called. setTimeout(() => console. log('Initial timeout!'

How do I clear setTimeout in React?

Clearing setTimeout A setTimeout timer must be cleared and handle properly, otherwise, you may experience adverse side effects in your code. To clear or cancel a timer, you call the clearTimeout(); method, passing in the timer object that you created into clearTimeout().

Is there a limit for setTimeout?

Maximum delay value Browsers including Internet Explorer, Chrome, Safari, and Firefox store the delay as a 32-bit signed integer internally. This causes an integer overflow when using delays larger than 2,147,483,647 ms (about 24.8 days), resulting in the timeout being executed immediately.


Do

setTimeout(
    function() {
        this.setState({ position: 1 });
    }
    .bind(this),
    3000
);

Otherwise, you are passing the result of setState to setTimeout.

You can also use ES6 arrow functions to avoid the use of this keyword:

setTimeout(
  () => this.setState({ position: 1 }), 
  3000
);

setTimeout(() => {
  this.setState({ position: 1 });
}, 3000);

The above would also work because the ES6 arrow function does not change the context of this.


Anytime we create a timeout we should s clear it on componentWillUnmount, if it hasn't fired yet.

      let myVar;
         const Component = React.createClass({

            getInitialState: function () {
                return {position: 0};    
            },

            componentDidMount: function () {
                 myVar = setTimeout(()=> this.setState({position: 1}), 3000)
            },

            componentWillUnmount: () => {
              clearTimeout(myVar);
             };
            render: function () {
                 return (
                    <div className="component">
                        {this.state.position}
                    </div>
                 ); 
            }

        });

ReactDOM.render(
    <Component />,
    document.getElementById('main')
);

I know this is a little old, but is important to notice that React recomends to clear the interval when the component unmounts: https://reactjs.org/docs/state-and-lifecycle.html

So I like to add this answer to this discussion:

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }
  componentWillUnmount() {
    clearInterval(this.timerID);
  }

setState is being invoked immediately due to the parenthesis! Wrap it in an anonymous function, then call it:

setTimeout(function() {
    this.setState({position: 1})
}.bind(this), 3000);

You didn't tell who called setTimeout

Here how you call timeout without calling additional functions.

1. You can do this without making additional functions.

setTimeout(this.setState.bind(this, {position:1}), 3000);

Uses function.prototype.bind()

setTimeout takes the location of the function and keeps it in the context.

2. Another way to do the same even by writing even less code.

setTimeout(this.setState, 3000, {position:1});

Probably uses the same bind method at some point

The setTimeout only takes the location of the function and the function already has the context? Anyway, it works!

NOTE: These work with any function you use in js.


Your code scope (this) will be your window object, not your react component, and that is why setTimeout(this.setState({position: 1}), 3000) will crash this way.

That comes from javascript not React, it is js closure


So, in order to bind your current react component scope, do this:

setTimeout(function(){this.setState({position: 1})}.bind(this), 3000);

Or if your browser supports es6 or your projs has support to compile es6 to es5, try arrow function as well, as arrow func is to fix 'this' issue:

setTimeout(()=>this.setState({position: 1}), 3000);