REACT介绍文档第5节,讲了一些组件生命周期的函数,包括:componentDidMount()、componentWillUnmount(),第3节还介绍了render()、setState()
,这些都是预定义函数。
tick()是自定义函数,constructor()是构造函数。
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
componentDidMount() {
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')
);
让我们来快速概括一下发生了什么和这些方法的调用顺序:
- 当
<Clock />
被传给ReactDOM.render()
的时候,React 会调用Clock
组件的构造函数。因为Clock
需要显示当前的时间,所以它会用一个包含当前时间的对象来初始化this.state
。我们会在之后更新 state。 - 之后 React 会调用组件的
render()
方法。这就是 React 确定该在页面上展示什么的方式。然后 React 更新 DOM 来匹配Clock
渲染的输出。 - 当
Clock
的输出被插入到 DOM 中后,React 就会调用ComponentDidMount()
生命周期方法。在这个方法中,Clock
组件向浏览器请求设置一个计时器来每秒调用一次组件的tick()
方法。 - 浏览器每秒都会调用一次
tick()
方法。 在这方法之中,Clock
组件会通过调用setState()
来计划进行一次 UI 更新。得益于setState()
的调用,React 能够知道 state 已经改变了,然后会重新调用render()
方法来确定页面上该显示什么。这一次,render()
方法中的this.state.date
就不一样了,如此以来就会渲染输出更新过的时间。React 也会相应的更新 DOM。 - 一旦
Clock
组件从 DOM 中被移除,React 就会调用componentWillUnmount()
生命周期方法,这样计时器就停止了。
调用顺序也比较好理解,首先ReactDOM.render()调用Clock的构造函数
constructor(),然后REACT调用Clock的render()函数,进入生命周期后先调用
ComponentDidMount(),这里遇到了个问题,ComponentDidMount()中的setInterval()是怎么做到每隔1秒调用一次
tick()
的?
实际上这个问题已经不在REACT范畴了,setInterval()属于HTML DOM方法,setInterval()函数本身只执行一次,setInterval()内部会设置计划每秒执行 tick(),具体细节这里不必关心。
setInterval()函数的返回值是一个数字,这个数字可以传递给 Window.clearInterval() 从而取消对 code 的周期性执行的值。而this.timerID = setInterval()仅仅是把定时器函数返回的数值保存在Clock实例的某个属性中,等待Clock组件生命周期结束时,调用componentWillUnmount()
中的clearInterval()时,将标识定时器的数值传入,来终止这个定时器。timerID不是预定义属性,可以改成其他名称,比如timer1。第一次看我有点糊涂,以为是REACT通过this.timerID不停的调用setInterval()函数,实际上setInterval()执行后,定时器就自动开始每1秒执行一次了。
https://www.w3school.com.cn/jsref/met_win_setinterval.asp
而本文的重点是setState()函数,这是REACT的预定义函数,当调用这个函数时,REACT就知道状态改变了,就会在setState()函数执行后,自行调用render()
方法重新渲染页面。
https://react.docschina.org/docs/state-and-lifecycle.html