react生命周期
一、react 16之前生命周期大的来分为4个阶段
1、第一阶段,初始化(Initial);初始默认数据
2、第二阶段,组件挂载(Mount);组件挂载显示在UI上
3、第三阶段,组件的更新(Update);在state或者props有数据变化
4、第四阶段,组件的卸载(Unmount);不再调用该组件
在每个阶段中有各自不同的函数代表不同的节点,下图表示各阶段以及各阶段中的关系;
第一阶段initial:
初始化state或者props;在react组件中construtor构造中的数据可以看作state的初始化
第二阶段Mount:
组件挂载到页面阶段;有2个函数节点;componentWillMount() 和 componentDidMount(),
1、componentWillMount() 将要挂载,
在render之前调用, 这是在render对初始化state进行修改的一个路径,比如获取缓存的数据。
2、render
创建一个虚拟的DOM用来表示组件的输出
3、componentDidMount() 挂载完成,
render方法执行后会渲染出真实的DOM,可通过方法getDomNode()获取原生的Dom
3、1:在render之后调用,比如发送ajax
3、2:为什么ajax要放在componentDidMount()之中?
因为ajax是异步的,假如ajax在componentWillMount()中,在componentWillMount中异步请求的数据可能还没获取到,已经render了,可能会导致页面空白,程序出错执行不下去。
第三阶段存在期的update
update是指state或者props数据的变化
1、state的更改
shouldComponentUpdate(nextProps, nextState), 默认返回true, 在此函数中可进行页面渲染的优化,可以减少不必要的render,比如:
shouldComponentUpdate(nextProps, nextState) {
if (JSON.stringfy(nextState) !== JSON.stringfy(this.state)) {
return true; // 允许页面重新渲染
} else {
return false; // 避免不必要的渲染
}
}
当没有shouldComponentUpdate()时,算法会比较是否为React.PurComponent,如果是React.PurComponent则进行浅比较(使用Object.is()进行比较,如果是负复杂的数据可能比较不出来)没有递归进行深层次的比较;如果是React.Component则进行深比较。对于性能方面推荐使用React.PureComponent,因为state更新或者父组件的props更新会导致render; 而React.Component在state更新和父组件的state更新都会导致render,其实就子组件而言对于父组件没必要的state更新是没有必要重新render的。
1.1、componmentWillUpdate()
在state或者props变化后并且在页面渲染前调用,在这个函数中不能使用this.setState来修改状态。这个函数调用后就会把nextProps和nextState分别设置到this.props和this.state中。
1.2、render()
重新渲染真实的Dom
1.3、componentDidUpdate()
组件更新结束之后执行,可在这里对渲染好的Dom更改操作
2、props更改
componentWillReceiveProps(nextProps)
在props更改时调用,然后执行1.1-->1.2-->1.3
第四阶段unmonut:
componentWillUnmount()
卸载组件,做一些清理工作,比如清除组件中使用的定时器,清除componentDidMount中手动创建的DOM元素等,以避免引起内存泄漏。
二、react16.4生命周期
生命周期图:参考官网 截图显示如下
分为三阶段:挂载、更新、卸载
1、第一阶段:挂载
1.1 constructor()
在组件挂载前调用。在为React.Component内使用constructor(props)构造时,要调用super(props), 否则组件内使用this.props会出错。
这个是非必须的,当需要初始化state的时候需要在constructor()中构造,没有state的初始化时不需要constructor()
1.2 getDerivedStateFromProps(props, state)
会在render前调用,在后续的初始化挂载和更新时都会调用,返回一个对象来更新state
1.3 render()
1.4 componentDidMount
会在组件挂载后立即调用,依赖DOM的初始化可以放在这里
* 去除了componentWillMount()
2、第二阶段:更新
2.1 getDerivedStateFromProps()
2.2 shouldComponentUpdate()
2.3 render()
2.4 getSnapshotBeforeUpdate(prevProps, prevState)
在最近一次渲染输出(提交到 DOM 节点)之前调用。它使得组件能在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置)。此生命周期的任何返回值将作为参数传递给 componentDidUpdate()
。
2.5 componentDidUpdate()
*删除了componentWillReceiveProps() 和 componentWillUpdate
3、第三阶段:卸载
componentWillUnmount
上述博文中如有错误或表述有疑问之处,感谢各位小伙伴的积极指出。