REACT介绍文档第5节,讲了一些组件生命周期的函数,包括:componentDidMount()、componentWillUnmount(),第3节还介绍了render()、setState(),这些都是预定义函数。
1 | class Clock extends React.Component { |
tick()是自定义函数,constructor()是构造函数。
让我们来快速概括一下发生了什么和这些方法的调用顺序:
- 当
被传给 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秒执行一次了。
而本文的重点是setState()函数,这是REACT的预定义函数,当调用这个函数时,REACT就知道状态改变了,就会在setState()函数执行后,自行调用render()
方法重新渲染页面。