前言:
React生命周期,生命周期在类组件中是很重要的一部分知识点,学好且充分理解生命周期方法,可以对我们日常的开发中起到不可忽视的作用。函数组件自出现hooks以来,也可以优雅的使用hooks,弥补函数组件没有生命中周期的缺憾。
组件生命周期执行过程:
类组件生命周期的执行基本可以分为三个阶段:
- 初始化阶段
- 更新阶段
- 销毁阶段
这三个阶段的执行基本都在mountClassInstance和 updateClassInstance 这两个方法中执行的。
1、初始化阶段: 初始化阶段首先执行mountClassInstance方法用来实例化组件,constructor在此方法中被执行。在组件实例化后 便会调用mountClassInstance进行组件初始化。
function mountClassInstance(workInProgress,ctor,newProps,renderExpirationTime){
const instance = workInProgress.stateNode;
const getDerivedStateFromProps = ctor.getDerivedStateFromProps;
if (typeof getDerivedStateFromProps === 'function') {
/* ctor 就是我们写的类组件,获取类组件的静态方法 */
const partialState = getDerivedStateFromProps(nextProps, prevState);
/* 这个时候执行 getDerivedStateFromProps 生命周期 ,得到将合并的state */
const memoizedState = partialState === null || partialState === undefined ? prevState : Object.assign({}, prevState, partialState);
// 合并state
workInProgress.memoizedState = memoizedState;
instance.state = workInProgress.memoizedState;
/* 将state 赋值给我们实例上,instance.state 就是我们在组件中 this.state获取的state*/ }
if(typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && typeof instance.componentWillMount === 'function' ){
instance.componentWillMount();
/* 当 getDerivedStateFromProps 和 getSnapshotBeforeUpdate 不存在的时候 ,执行 componentWillMount*/ } }
参考文献:React实战进阶指南
getDerivedStateFromProps执行: getDerivedStateFromProps是初始化阶段执行的第二个生命周期,它是直接从ctor类上绑定的静态方法,传入props, state,返回值将和之前的state合并,作为新的state 传递给组件实例使用。
componentWillMount执行: 如果存在 getDerivedStateFromProps 和getSnapshotBeforeUpdate 就不会执行生命周期componentWillMount。
render函数执行: mountClassInstance函数到此阶段执行结束, updateClassInstance函数,在mountClassInstance执行完成后,执行render函数,生成了chuldren,react 即将调用reconcileChildren方法调和children。
componentDidMount执行: 在react调和完所有节点后,组件初始化进入commit阶段,会调用componentDidMount生命周期,
function commitLifeCycles(finishedRoot,current,finishedWork){
switch (finishedWork.tag)
{ /* fiber tag 在第一节讲了不同fiber类型 */
case ClassComponent: { /* 如果是 类组件 类型 */
const instance = finishedWork.stateNode /* 类实例 */
if(current === null){ /* 类组件第一次调和渲染 */
instance.componentDidMount()
}else{
/* 类组件更新 */
instance.componentDidUpdate(prevProps,prevStateinstance.__reactInternalSnapshotBeforeUpdate);
}
}
}
}
componentDidMount和componentDidUpdate的执行时机是相同的,不同的是componentDidMount针对组件初始化componentDidUpdate针对的是组件再更新,到此初始化阶段,生命周期执行完毕。
执行顺序:constructor=>getDerivedStateFromProps或componentWillMount=> render=> componentDidMount。
2、更新阶段: 类组件在更新阶段,componentDidUpdate函数中 current 参数不为null,说明组件已经被挂载过了,就会按照更新逻辑处理。
function updateClassInstance(current,workInProgress,ctor,newProps,renderExpirationTime){
const instance = workInProgress.stateNode; // 类组件实例
const hasNewLifecycles = typeof ctor.getDerivedStateFromProps === 'function' // 判断是否具有 getDerivedStateFromProps 生命周期
if(!hasNewLifecycles && typeof instance.componentWillReceiveProps === 'function' ){
if (oldProps !== newProps || oldContext !== nextContext) { // 浅比较 props 不相等
instance.componentWillReceiveProps(newProps, nextContext); // 执行生命周期 componentWillReceiveProps
}
}
let newState = (instance.state = oldState);
if (typeof getDerivedStateFromProps === 'function') {
ctor.getDerivedStateFromProps(nextProps,prevState) /* 执行生命周期getDerivedStateFromProps ,逻辑和mounted类似 ,合并state */
newState = workInProgress.memoizedState;
}
let shouldUpdate = true
if(typeof instance.shouldComponentUpdate === 'function' ){ /* 执行生命周期 shouldComponentUpdate 返回值决定是否执行render ,调和子节点 */
shouldUpdate = instance.shouldComponentUpdate(newProps,newState,nextContext,);
}
if(shouldUpdate){
if (typeof instance.componentWillUpdate === 'function') {
instance.componentWillUpdate(); /* 执行生命周期 componentWillUpdate */ }
}
return shouldUpdate
}
componentWillReceiveProps执行: 判断getDerivedStateFromProps生命周期如果不存在,便开始执行componentWillReceiveProps生命周期,componentWillReceiveProps生命周期传入newProps和nextContext两个参数,
getDerivedStateFromProps执行: 返回值用于合并state,生成新的state。
shouldComponentUpdate执行: 传入新的props, state, context,返回值决定是否继续执行render函数,调和子节点(getDerivedStateFromProps的返回值可以作为新的state传递给shouldComponentUpdate)
render函数执行: render函数执行会得到一个新的React element元素,然后继续调和子节点。
getSnapshotBeforeUpdate执行:
function commitBeforeMutationLifeCycles(current,finishedWork){
switch (finishedWork.tag) {
case ClassComponent:{
const snapshot = instance.getSnapshotBeforeUpdate(prevProps,prevState) /* 执行生命周期 getSnapshotBeforeUpdate */
instance.__reactInternalSnapshotBeforeUpdate = snapshot; /* 返回值将作为 __reactInternalSnapshotBeforeUpdate 传递给 componentDidUpdate 生命周期 */
}
}
}
getSnapshotBeforeUpdate执行也在commit阶段,commit 分为beforeMutation阶段, Mutation阶段, Layout阶段,分别对对应,DOM修改前,DOM修改中, DOM修改后, 三个阶段。getSnapshotBeforeUpdate发生在beforeMutation阶段,生命周期的返回值将作为第三个参数 __reactInternalSnapshotBeforeUpdate 传递给componentDidUpdate生命周期。
componentDidUpdate执行: 到此生命周期,DOM完成修改,可以操作修改后的DOM,至此更新阶段的生命周期执行完毕。