前言
React 的组件可以定义为 class 或函数的形式。class 组件目前提供了更多的功能。
什么是生命周期
组件从 被创建 到 被销毁 的过程称为组件的生命周期。 组件的生命周期有三个状态:
- 组件挂载时
- 组件更新时
- 组件卸载时
组件的生命周期也可以分为三个阶段:
- Render 阶段: 构建Fiber树和生成effectList
- Pre-commit 阶段: 准备commit 之前,可以获取当前 DOM 的快照(snapshot)
- Commit 阶段: 运行effects,准备更新DOM
如下图,是生命周期图谱:
每个组件都包含 “生命周期方法”,你可以重写这些方法,以便于在运行过程中特定的阶段执行这些方法。
生命周期方法
constructor
在 React 组件挂载之前,会调用它的构造函数。在为 React.Component 子类实现构造函数时,应在其他语句之前调用 super(props)。否则,this.props 在构造函数中可能会出现未定义的 bug。
通常,在 React 中,构造函数仅用于以下两种情况:
-
通过给 this.state 赋值对象来初始化内部 state。
-
为事件处理函数绑定实例。
constructor(props) {
super(props);
this.state = { counter: 0 };
this.handleClick = this.handleClick.bind(this);
}
static getDerivedStateFromProps()(不常用)
static getDerivedStateFromProps(props, state)
getDerivedStateFromProps 会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。它应返回一个对象来更新 state,如果返回 null 则不更新任何内容。
此方法适用于罕见的用例,即 state 的值在任何时候都取决于 props。
render()
render()
render() 方法是 class 组件中唯一必须实现的方法。
当 render 被调用时,它会检查 this.props 和 this.state 的变化并返回结果。
componentDidMount()
componentDidMount()
componentDidMount() 会在组件挂载后(插入 DOM 树中)立即调用。依赖于 DOM 节点的初始化应该放在这里。如需通过网络请求获取数据,此处是实例化请求的好地方。
shouldComponentUpdate() (不常用)
shouldComponentUpdate(nextProps, nextState)
根据 shouldComponentUpdate() 的返回值,判断 React 组件的输出是否受当前 state 或 props更改的影响。默认行为是 state 每次发生变化组件都会重新渲染。大部分情况下,你应该遵循默认行为。
当 props 或 state 发生变化时,shouldComponentUpdate() 会在渲染执行之前被调用。返回值默认为 true。首次渲染或使用 forceUpdate() 时不会调用该方法。
getSnapshotBeforeUpdate() (不常用)
getSnapshotBeforeUpdate(prevProps, prevState)
getSnapshotBeforeUpdate() 在最近一次渲染输出(提交到 DOM 节点)之前调用。它使得组件能在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置)。此生命周期方法的任何返回值将作为参数传递给 componentDidUpdate()。
componentDidUpdate()
componentDidUpdate(prevProps, prevState, snapshot)
componentDidUpdate() 会在更新后会被立即调用。首次渲染不会执行此方法。
当组件更新后,可以在此处对 DOM 进行操作。如果你对更新前后的 props 进行了比较,也可以选择在此处进行网络请求。(例如,当 props 未发生变化时,则不会执行网络请求)。
componentDidUpdate(prevProps) {
// 典型用法(不要忘记比较 props):
if (this.props.userID !== prevProps.userID) {
this.fetchData(this.props.userID);
}
}
你也可以在 componentDidUpdate() 中直接调用 setState(),但请注意它必须被包裹在一个条件语句里,正如上述的例子那样进行处理,否则会导致死循环。它还会导致额外的重新渲染,虽然用户不可见,但会影响组件性能。
如果组件实现了 getSnapshotBeforeUpdate() 生命周期(不常用),则它的返回值将作为 componentDidUpdate() 的第三个参数 “snapshot” 参数传递。否则此参数将为 undefined
componentWillUnmount()
componentWillUnmount()
componentWillUnmount() 会在组件卸载及销毁之前直接调用。在此方法中执行必要的清理操作,例如,清除 timer,取消网络请求或清除在 componentDidMount() 中创建的订阅等。
componentWillUnmount() 中不应调用 setState(),因为该组件将永远不会重新渲染。组件实例卸载后,将永远不会再挂载它。
总结
以上八个就是最新版本的react的生命周期方法。