什么是生命周期?
所谓的React生命周期,就是指组件从被创建出来,到被使用,最后被销毁的这么一个过程。而在这个过程中,React提供了我们会自动执行的不同的钩子函数,我们称之为生命周期函数。**组件的生命周期大致分为三个阶段:组件挂载阶段,组件更新阶段,组件销毁卸载阶段 **
生命周期执行顺序
挂载
constructor
(构造函数在类组件中比较常见)getDerivedStateFromProps
render
(render函数)-----只能访问this.props和this.state,不允许修改状态和DOM输出componentDidMount
(组件挂载)-------成功render并渲染完成真实DOM之后触发,可以修改DOM
更新
getDerivedStateFromProps
shouldComponentUpdate
render
(render函数)getSnapshotBeforeUpdate
componentDidUpdate
(组件更新)--------可以修改DOM
卸载
- `componentWillUnmount(组件销毁)
图解
生命周期详解
constructor()
constructor()
在React组件挂载之前被调用一次,在为React.Component子类实现构造函数时,应在其他语句之前调用 super()
super的作用:将父类的this对象继承给子类。
通常,React构造函数仅用于以下两种情况:
- 来初始化函数内部 state
- 为 事件处理函数 绑定实例
如果不初始化
state
或不进行方法绑定,则不需要写constructor()
, 只需要设置this.state
即可
不能在
constructor()
构造函数内部调用this.setState()
, 因为此时第一次render()
还未执行,也就意味DOM节点还未挂载
static getDerivedStateFromProps(nextProps, state)
getDerivedStateFromProps()
在调用 render
方法之前调用,在初始化和后续更新都会被调用
返回值:需要返回一个对象来更新
state
, 如果没有指定返回值,React 会发出警告;React 需要用这个返回值来更新/派生组件的 state;如果不需要,最好直接省略这个方法,否则需要返回 null不会进行更新
参数: 第一个参数为即将更新的
props
值, 第二个参数为上一个状态的state
, 可以比较props
和state
来加一些限制条件,防止无用的state更新,即 state 的值在任何时候都取决于 props。
注意:
getDerivedStateFromProps
是一个静态函数,静态方法不依赖组件实例而存在。所以不能使用this, 也就是只能作一些无副作用的操作
至于为什么要这样做?请移步 Morgan大佬 - 知乎
值得一提的是,getDerivedStateFromProps 在更新和挂载两个阶段都会“出镜”。这是因为“派生 state”这种诉求不仅在 props 更新时存在,在 props 初始化的时候也是存在的。React 16 以提供特定生命周期的形式,对这类诉求提供了更直接的支持。
render()
render()
方法是class组件中唯一必须实现的方法,用于渲染dom, render()
方法必须返回reactDOM
注意: 不要在
render
里面setState
, 否则会触发死循环导致内存崩溃
componentDidMount()
componentDidMount()
在组件挂载后 (插入DOM树后) 立即调用,componentDidMount()
是发送网络请求、启用事件监听方法、数据初始化的好时机,并且可以在 此钩子函数里直接调用 setState()
shouldComponentUpdate(nextProps, nextState)
shouldComponentUpdate()
在组件更新之前调用,可以控制组件是否进行更新, 返回true时组件更新, 返回false则不更新,默认返回的是true,也就是只要state发生改变,就会调用render方法
包含两个参数,第一个是即将更新的 props 值,第二个是即将更新后的 state 值,可以根据更新前后的 props 或 state 来比较加一些限制条件,决定是否更新,进行性能优化
不建议在
shouldComponentUpdate()
中进行深层比较或使用JSON.stringify()
。这样非常影响效率,且会损害性能
不要
shouldComponentUpdate
中调用 setState(),否则会导致无限循环调用更新、渲染,直至浏览器内存崩溃
可以使用内置
PureComponent
组件替代
getSnapshotBeforeUpdate(prevProps, prevState)
getSnapshotBeforeUpdate()
在最近一次的渲染输出被提交之前调用。也就是说,在 render 之后,即将对组件进行挂载时调用。
它可以使组件在 DOM 真正更新之前捕获一些信息(例如滚动位置),此生命周期返回的任何值都会作为参数传递给
componentDidUpdate()
。如不需要传递任何值,那么请返回 null
componentDidUpdate(prevProps, prevState, snapshot)
componentDidUpdate()
会在更新后会被立即调用。首次渲染不会执行
包含三个参数,第一个是上一次props值。 第二个是上一次state值。如果组件实现了
getSnapshotBeforeUpdate()
生命周期(不常用),第三个是“snapshot” 参数传递
可以进行前后props的比较进行条件语句的限制,来进行
setState()
, 否则会导致死循环
componentWillUnmount()
componentWillUnmount()
在组件即将被卸载或销毁时进行调用。
此生命周期是取消网络请求、移除监听事件、清理 DOM 元素、清理定时器等操作的好时机