小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
当讨论React组件生命周期,基本是围绕着类组件进行讨论的,因为目前有些观点认为:当函数组件引入Hooks之后,函数组件也具备了生命周期
下面一起看一看React16.3之后类组件的生命周期的三个阶段:挂载、更新和卸载
挂载阶段
挂载过程在组件的一生中仅会发生一次,在这个过程中,组件被初始化,然后会被渲染到真实 DOM 里,完成“首次渲染”
constructor
constructor 是类通用的构造函数,该方法仅仅在挂载阶段的时候被调用一次,常用于初始化 state 与绑定函数
import React from 'react'
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = { name: "nordon" };
this.clickHandler = this.clickHandler.bind(this);
}
}
随着技术的发展,目前已经渐渐很少有人还在constructor中这么做了
移除constructor原因:
- constructor是class中的初始化函数,和React生命周期并没太直接的关系
- constructor中并不适合处理初始化以外的逻辑
- 代码会变得整洁
import React from 'react'
class Demo extends React.Component {
state = { name: "nordon" };
clickHandler = () => {}
}
getDerivedStateFromProps
React 16.3 生命周期 getDerivedStateFromProps,其用法如下
static getDerivedStateFromProps(props, state)
其作用是使组件在 props 变化时派生 state,触发时机:
- 当 props 被传入时
- state 发生变化时;
- forceUpdate 被调用时。
render
render 函数返回的 JSX 结构,用于描述具体的渲染内容
由于其是一个纯函数,因此千万不要在里面产生具有副作用的操作,比如调用setState、绑定事件等
componentDidMount
在浏览器中,触发componentDidMount时,我们是可认为界面已经绘制完成,主要用于组件加载完成时处理一些事情,比如发起请求
更新阶段
getDerivedStateFromProps
同挂载阶段
shouldComponentUpdate
该方法通过返回 true 或者 false 来确定是否需要触发新的渲染。因为渲染触发最后一道关卡,所以也是性能优化的必争之地。通过添加判断条件来阻止不必要的渲染。
shouldComponentUpdate(nextProps, nextState) {
// 浅比较仅比较值与引用,并不会对 Object 中的每一项值进行比较
if (shadowEqual(nextProps, this.props) || shadowEqual(nextState, this.state) ) {
return true
}
return false
}
render
同挂载阶段
getSnapshotBeforeUpdate
与 componentDidUpdate 一起,这个新的生命周期涵盖过时componentWillReceiveProps 的所有用例。
getSnapshotBeforeUpdate 方法是配合 React 新的异步渲染的机制,在 redner前被调用,返回值将作为 componentDidUpdate 的第三个参数。
getSnapshotBeforeUpdate(prevProps, prevState) {
// todo ...
}
componentDidUpdate
getSnapshotBeforeUpdate返回的值回作为第三个参数传递
componentDidUpdate(prevProps, prevState, valueFromSnapshot) {
// 从 getSnapshotBeforeUpdate 获取到的值是: valueFromSnapshot
}
卸载阶段
componentWillUnmount
该函数主要用于执行清理工作。一个比较常见的 Bug 就是忘记在 componentWillUnmount 中取消定时器,导致定时操作依然在组件销毁后不停地执行。所以一定要在该阶段解除事件绑定,取消定时器