react的生命周期分为三大周期,整理如图:
![](https://i-blog.csdnimg.cn/blog_migrate/72f24fe8dd7bf7fb52d87a4564915ab1.png)
在挂载(创建)时
getDefaultProps(旧):定义默认属性数据。
getInitialState(旧):初始化默认状态数据。
componentWillMount(旧):组件即将被构建。已初始化数据,但没有渲染DOM。
constructor(props) :数据初始化。接收props和context。
static getDerivedStateFromProps(nextProps,prevState)(新):从props中获取state。适用于罕见用例,即当state的值任何时候都取决于props时。如果返回对象,更新state;返回null,不更新。
render:渲染组件。class组件中唯一必须实现的方法。
render会插入jsx生成的Dom树,react会生成虚拟Dom树。每次更新,react会根据其diff算法比较更新前后的新旧Dom树。之后,找到最小差异的Dom节点,并重新渲染。
render被调用时会检查this.props和this.state的变化,并返回以下类型之一:
(1)通过jsx创建的react元素
(2)数组或fragments(使render可返回多个元素)
(3)Protals:可以渲染子节点到不同的Dom树上
(4)字符串或数值类型:在Dom中会被渲染成文本节点
(5)布尔类型或null:什么都不渲染
componentDidMount:组件挂载后(插入到Dom树)立即调用。在此可以调用ajax、setState或添加订阅(需要在卸载之后取消点阅)
在更新(存在期)时
componentWillReceiveProps(nextProps)(旧):组件即将接收新的属性数据。即在已挂载的组件接收新的props前调用。
static getDirevedStateFromProps(nextProps,prevState)(新):替换componentWillReceivedProps
shouldComponentUpdate(nextProps,nextState):判断组件是否应该更新。在渲染前调用,默认返回true。主要用于性能优化。浅层比较。
componentWillUpdate(nextProps,nextState)(旧):组件即将更新。不能调用setState
render:渲染组件。
getSnapShotBeforeUpdate(prevProps,prevState)(新):在最后一次渲染(提交到Dom节点)前调用,替换componentWillUpdate。
会在组件更新前获取Dom节点的信息(如滚动位置),该方法返回的所用值都会作为参数传给componentDidUpdate中的第三个参数。该方法不常用,可用于UI处理中。
componentDidUpdate(prevProps,precState,snapshot):在更新之后立即调用。
首次渲染不会调用,之后的每次更新渲染都会被调用。可以使用setState,但要包含在if语句中,否则一直更新会造成死循环。可在此处对Dom操作(可以根据比较前后props,进行网络请求)。
在卸载(销毁期)时
componentWillUNmount:组件即将被卸载。
在组件卸载和销毁前调用。取消timer、订阅、监听。不应调用setState,该组件永远不会重新渲染。
从 Class 迁移到 Hook
生命周期方法要如何对应到 Hook?
constructor:函数组件不需要构造函数。可以通过调用 useState 来初始化 state。如果计算的代价比较昂贵,可以传一个函数给 useState。
getDerivedStateFromProps:改为 在渲染时 安排一次更新。
shouldComponentUpdate:详见 React.memo .
render:这是函数组件体本身。
componentDidMount, componentDidUpdate, componentWillUnmount:useEffect Hook 可以表达所有这些(包括 不那么 常见 的场景)的组合。
getSnapshotBeforeUpdate,componentDidCatch 以及 getDerivedStateFromError:目前还没有这些方法的 Hook 等价写法,但很快会被添加。