react的生命周期
React的生命周期,可以总结为初始化、加载、渲染、销毁四个阶段。我们先实现v16.4之前的生命周期,然后再想办法改写为最新的生命周期:
- componentWillMount(第一次render前调用一次)
- componentDidMount(第一次render后调用一次)
- render(渲染)
- componentWillReceiveProps(props变化就调用一次)
- componentWillUpdate(第一次render后每次render前)
- componentDidUpdate(第一次render后每次render后)
- componentWillunmount(销毁)
componentWillMount()和componentWillUpdate()
这是在第一次render前调用的生命周期,不建议在这里进行ajax请求,因为有可能在render前就返回结果后产生无效。 在mountComponent中,调用_tempDom.render()前,根据_tempDom有没有container判断是第一次渲染还是非第一次渲染:
if (vDom.isReactComponent) {
const _tempDom = vDom;
/**
* 第一次render前调用componentWillMount()
* 其余时候调用componentWillUpdate()
*/
if (!_tempDom._container) {
_tempDom.componentWillMount && _tempDom.componentWillMount();
} else {
_tempDom.componentWillUpdate && _tempDom.componentWillUpdate();
}
_tempDom._container = container;
vDom = _tempDom.render();
}
打印结果:
componenDidMount()和componentDidUpdate
同样是在mountComponent中,如果是第一次渲染完成就调用componentDidMount(),如果不是第一次渲染完成就在render后调用componentDidMount,由于渲染完后无论是不是第一次,_tempDom.container都会挂载到真实dom内,所以通过标识符来告诉引擎是不是第一次执行。
if (vDom.isReactComponent) {
const _tempDom = vDom;
/**
* 第一次render前调用componentWillMount()
* 其余时候调用componentWillUpdate()
*/
let flag = false;
if (!_tempDom._container) {
_tempDom.componentWillMount && _tempDom.componentWillMount();
flag = true;
} else {
_tempDom.componentWillUpdate && _tempDom.componentWillUpdate();
}
_tempDom._container = container;
vDom = _tempDom.render();
if (flag) {
_tempDom.componentDidMount();
} else {
_tempDom.componentDidUpdate();
}
}
componentWillReceiveProps()和shouldComponentUpdate()
componentWillReceiveProps()是每次react组件接受到的props改变时,就会调用的生命周期方法,shouldComponentUpdate()返回的是一个布尔值,如果返回的是false,则就算props变化了,react组件也不会重新渲染。
但是如果想靠比较shouldComponentUpdate内的新旧props来优化是否要渲染,不太妥当,建议使用pureComponent和React.memo()
componentWillReceiveProps第一次render后不会调用,之后每次render时调用。
但是这里牵涉到了react关于如何更新父组件的state,以及判断节点是否变化之间的内容,所以打算放到之后的diff算法中一起讨论。
下一篇将去分析diff算法,最后形成一个能成功运行的简易生命周期~