我一直在玩其官方网站上的React Example:
我的问题有点棘手:
我有时钟Component
,它使用当前时间进行屏幕显示
new Date().toLocaleTimeString()
代码:此代码工作正常
import React, { Component } from 'react'
import ReactDOM from 'react-dom';
class Clock extends Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(), //problematic line
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>
)
}
}
function Root() {
const element = <Clock />
ReactDOM.render(
element,
document.getElementById('root')
);
}
export default Root;
问题但问题是,当我将() => this.tick()
更改为this.tick()
或this.tick
时,计时器仅第一次运行,并且不会连续运行。在这种情况下我很困惑:
任何人都可以告诉我在这种情况下() => this.tick()
和this.tick()
之间有什么区别,或者为什么当我将这个() => this.tick()
改成this.tick()
时计时器没有更新?
如果你查找函数setInterval,你会注意到第一个参数(firstArg)必须是一个返回另一个函数的函数,第二个参数(secondArg)必须是一个数字或一个数字数组,表示你想要重复的延迟函数作为第一个参数给出。
setInterval(firstArg, secondArg) // typeof firstArg must be a function that returns something
在你的情况下,你只需传递'this.tick()'或'this.tick',它不会返回任何内容。由于this.tick()不返回任何内容,因此setInterval无法继续更新“日期”状态。
如果你将tick()更改为
tick() {
return () => this.setState({ //returns anonymous function
date: new Date()
});
}
要么
tick = () => () => {
this.setState({
date: new Date()
});
}
你可以做到这一点。
componentDidMount() {
this.timerID = setInterval(
this.tick()
1000
);
}
影响此代码工作的唯一区别是,
() => this.tick()
是一个函数
this.tick()
是一个函数调用语句。
因此set timer的第一个参数应该是在时间间隔之后调用的函数。当你将它更改为this.tick()时,setTimeout将尝试执行this.tick()(),这将无法正常工作。这是第一次初始化setTimeout函数时调用参数(这是一个函数)而不是初始化。
它是JavaScript中this的工作原理。
const object1 = {
method(){
setTimeout(function () { console.log(this) })
}
}
const object2 = {
method(){
setTimeout(() => { console.log(this) })
}
}
// the same as
var object3 = {
method: function method() {
var _this = this;
setTimeout(function() {
console.log(_this);
});
}
};
object1.method(); // window
object2.method(); // object2
object3.method(); // object3