Having this code in mind:
var Component = React.createClass({
getInitialState: function () {
return {position: 0};
},
componentDidMount: function () {
setTimeout(this.setState({position: 1}), 3000);
},
render: function () {
return (
<div className="component">
{this.state.position}
</div>
);
}
});
ReactDOM.render(
<Component />,
document.getElementById('main')
);
Isn't the state supposed to change only after 3 seconds? It's changing immediately.
My main goal here is to change the state every 3 seconds (with setInterval()
), but since it was not working, I tried setTimeout()
, which is not working either. Any lights on this? Thanks!
This question is related to
javascript
reactjs
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);
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);
You did syntax declaration error, use proper setTimeout declaration
message:() => {
setTimeout(() => {this.setState({opened:false})},3000);
return 'Thanks for your time, have a nice day !
}
Here how you call timeout without calling 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.
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.
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')
);
There's a 3 ways to access the scope inside of the 'setTimeout' function
First,
const self = this
setTimeout(function() {
self.setState({position:1})
}, 3000)
Second is to use ES6 arrow function, cause arrow function didn't have itself scope(this)
setTimeout(()=> {
this.setState({position:1})
}, 3000)
Third one is to bind the scope inside of the function
setTimeout(function(){
this.setState({position:1})
}.bind(this), 3000)
Try to use ES6 syntax of set timeout. Normal javascript setTimeout() won't work in react js
setTimeout(
() => this.setState({ position: 100 }),
5000
);
setTimeout(() => {
this.setState({ position: 1 });
}, 3000);
The above would also work because the ES6 arrow function does not change the context of this
.
Source: Stackoverflow.com