I think Rajesh has already explained it in the comments, still I will give it a try to explain.
An arrow function does not create its own this context, so this has its original meaning from the enclosing context i.e from where it is being called which is componentDidMount
in your case.
componentDidMount() {
// this refers to React.Component instance
this.timerID = setInterval(
() => this.tick(), // <----------------Same this is available here
1000
);
}
If you use bind you can achieve similar things via setting context via bind.
componentDidMount() {
// this refers to React.Component instance from inside cdm method
this.timerID = setInterval(
this.tick.bind(this), // <----------------Same this is available here
// We have set it react component instance via bind
1000
);
}
Now after all those just look only at this method declaration -
tick() {
this.setState({
date: new Date()
});
}
Upto this point we can not say exactly what will be the value of this
inside tick
.
We also can not say that 'setState
' will be available on this
or not.
Unless and until we see from where tick
will get called and what execution context will be attached to tick
at run time.
Now if we see from where tick is getting called - componentDidMount
.
componentDidMount
is react component's life cycle method and it ( associated context i.e this) definitely has setState
method available.
And in componentDidMount
we had set this
to react-component
context either via arrow function () => {}
or via bind
.
This is the reason because of which setState
is avaialble in tick
when called and you don't see any error.
But if you don't use arrow function or explicit bind you will be receiving following error on each time when setInterval
calls tick
function there by associating a global this with tick.
"message": "Uncaught TypeError: this.setState is not a function",
See the below code snippet via running to see the error
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
componentDidMount() {
// now this inside tick will be pointing to setIntervals execution context which could be global
this.timerID = setInterval(
this.tick,
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({
date: new Date()
});
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root">
</div>