生命周期
1、挂载阶段
在组件的挂载阶段,会依次调用以下生命周期函数。
1.constructor(props)
- 初始化组件
- 不要忘了加super
2.static getDerivedStateFromProps(props,state)
- 挂载阶段,获取当前的props和state,然后根据props来对state进行修改
- 静态方法,内部不能使用this方法
- 16.3新增
- 必须有返回值,返回值是对state的修改
- 组件初始时一定一定要定义state属性
3.componentWillMount
- 代表组件即将要挂载
- 16.3后不建议使用,在17.x中使用,建议写成UNSAFE_componentWillMount
- 不能和 getDerivedStateFromProps(props,state) 同时使用 4.render
- 更具return中的值生成虚拟DOM,然后提交给 ReactDOM 渲染真实的DOM 5.componentDidMount
- 组件已经挂载完毕,虚拟DOM已经添加到真实DOM中
2、更新阶段
react 组件更新的生命周期函数有三种不同的过程:父组件引起的当前组件更新、当前组件自己更新、forceUpdate
-
父组件更新引起当前组件更新
- React 16.3 及以后 与之前有差异
(1)React 16.3之前
- componentWillReceiveProps(nextProps)
- 在父组件更新后子组件接受到新的 Props 时触发,注意该函数调用的是 this.props 结果还是更新前的props,如果需要使用更新后的props,需要调用参数中接收到的nextProps
- shouldComponentUpdate(nextProps,nextState)
- 用于判断是否要进行组件的更新
- props 和 state 还是更新前的数据,使用更新后的传参数获取
- 必须有返回值,返回值为布尔值。 true 时,生命周期继续向下进行,组件继续更新。false 时,停止组件更新,不会调用后续的生命周期函数
- componentWillUpdate(nextProps,nextState)
- 代表组件即将更新
- props 和 state 的相关问题如上述
- render
- 根据新的 props 和 state 生成虚拟 DOM,然后讲新的虚拟DOM和旧的虚拟DOM对比找出更新点,更新真实DOM
- 这里的 props 和 state 是更新后的
- componentDidUpdate(prevProps,prevState)
-
代表组件已经更新完毕,真实DOM已经完成重新渲染
-
需要获取更新前的 props 和 state,可以通过参数接收
-
处理副作用(请求):获取真实DOM节点、数据请求
-
(2)React 16.3
React 16.3 中用 getDerivedStateFromProps 方法替换掉了 componentWillReceiveProps。从 React 16.3 起,componentWillReceiveProps 和 componentWillUpdate 逐渐被弃用,到 React 17.x 中使用他们需要加前缀 UNSAFE_,并且使用了 getDerivedStateFromProps 方法后,这俩不会再被调用。
- static getDerivedStateFromProps(newProps,newState)
- 在更新阶段,可以获取新的 props 和 state ,同样返回值是要对 state 做的修改
- shouldComponentUpdate
- 判断组件是否更新
- render
- 生成新的虚拟DOM
- getSnapshotBeforeUpdate(prevProps,prevState)
- react 16.3 新增
- 执行在 render 生成虚拟DOM之后,渲染真实DOM之前,用于获取渲染前的DOM快照
- 这里的this.state 和 this.props 已经是新的了,需要获取更新前的可以通过参数接收
- 必须要有返回值,返回值会传递给 componentDidUpdate
- componentDidUpdate(prevProps,prevState,snapshot)
-
16.3 中,新增第3个参数snapshot,用于接收 getSnapshotBeforeUpdate 传递过来的信息
-
处理副作用(请求):获取真实DOM节点、数据请求
-
-
组件自己更新
组件自己更新即在组件内部调用了 setState,引起当前组件的更新。组件自己更新经历过三个版本:16.3 之前、16.3、16.4及以后
- 在 React 16.3 之前 ,依次调用以下函数 :
- shouldComponentUpdate
- componentWillUpdate
- render
- componentDidUpdate
- 可以看到,这里组件更新不再监听 props 变化,只监听 state 的修改
- 在 React 16.3 中 ,由于生命周期函数有变化,组件自更新所调用的函数也跟着有变化,依次为:
- shouldComponentUpdate
- render
- getSnapshotBeforeUpdate
- componentDidUpdate
- 在 React 16.4 及以后,官方调整把组件自更新和父组件更新带来的组件更新做了统一,顺序为:
-
static getDerivedStateFromProps
-
shouldComponentUpdate
-
render
-
getSnapshotBeforeUpdate
-
componentDidUpdate
-
- 在 React 16.3 之前 ,依次调用以下函数 :
-
forceUpdate
强制更新,当组件依赖的数据不是 state 时,数据改变了,此时此刻希望视图也进行改变可以使用 forceUpdate 方法。forceUpdate 方法会强制视图更新,不会调用 shouldComponentUpdate。
import { Component } from 'react' let name = "name" class App extends Component { render() { return <div> <p>{name}</p> <button onClick={() => { name = "新名字"; this.forceUpdate(); // 不调用不会更新 }}></button> </div> } } export default App;
3、卸载阶段
组件卸载即把组件从 DOM 中删除。只有一个生命周期函数:componentWillUnmount ,用于监听组件即将卸载,通常用于在组件卸载时,删掉一些组件加在 全局 中的内容。
生命周期图谱地址:projects.wojtekmaj.pl/react-lifec…
16.3以前
16.3
16.4及以后
整理自《React 工程师修炼指南》