React生命周期
React 生命周期分为 mount、update、unmount 三个阶段。每个阶段对应两个生命周期(unmount 除外)。在 update 阶段还存在两个特殊的周期 shouldcomponentUpdate 和 componentWillReceiveProps。
生命周期方法
React v16.3.0 之前
1. componentWillMount()
- 调用时期
- 在
render()方法之前
- 在
- 说明
- 在组件挂载之前调用且全局只调用一次。
componentWillMount()是在render()之前执行,所以在这里使用setState()不会触发render()
2. render()
- 调用时期
componentWillMount()之后componentWillReceiveProps()之后componentWillUpdate()之后
- 说明
render()是必不可少的生命周期,用于渲染 DOM- 不能在
render()里修改state,修改state会引起render(),render()里又会再次修改state… 造成死循环。
3. componentDidMount()
- 调用时期
- 组件挂载完成之后调用,且全局只调用一次
- 说明
- 此时完成真实 DOM 元素插入,可以获取到真实
DOM元素及refs - 此时可以修改
state触发render() - 此时进行异步数据请求,可以保证在更新状态时组件挂载完成
- 此时完成真实 DOM 元素插入,可以获取到真实
4. componentWillReceiveProps(nextProps)
- 调用时期
- 已经挂载的组件接收到新的
props时 - 父组件重新渲染时
- 已经挂载的组件接收到新的
- 说明
- 该生命周期的触发时间为
props即将变化前 - 在该钩子内可以通过参数
nextProps获取变化后的props参数,通过this.props访问之前的props - 如果需要在
props发生变化时更新state,需要比较this.state和nextProps,然后使用setState来更新state
- 该生命周期的触发时间为
5. shouldComponentUpdate(nextProps, nextState)
- 调用时期
- 组件挂载之后,每次
state或props发生变化时调用shouldComponentUpdate判断是否需要重新渲染组件。
- 组件挂载之后,每次
- 说明
- 默认返回
true,需要重新render。返回false则不触发渲染 - 有一个例外,如果开发者调用this.forceUpdate强制更新,React组件会无视这个钩子
- 需要优化的情况 详情
- 如果
shouldComponentUpdate(nextProps, nextState)返回false,那么componentWillUpdate(nextProps, nextState),render(),componentDidUpdate()都不会被触发
- 默认返回
6. componentWillUpdate(nextProps, nextState)
- 调用时期
shouldComponentUpdate()生命周期钩子返回true,或者调用this.forceUpdate()之后
- 说明
componentWillUpdate()在每次更新前都会调用,在这里调用setState(),可能会陷入死循环- 如果
shouldComponentUpdate()返回了false,那么不会触发
7. componentDidUpdate(prevProps, prevState, snapshot)
- 调用时期
- 组件更新之后,在
componentWillUpdate()和render()之后
- 组件更新之后,在
- 说明
- 同样,在每次更新之后都会调用,所以使用
setState()可能会陷入死循环,需要自行判断 - 和
componentDidMount()类似,可以在这里操作 DOM 和 发起网络请求 - 如果
shouldComponentUpdate()返回了false,那么不会触发 - 搭配
getSnapshotBeforeUpdate生命周期钩子使用的时候,第三个参数是getSnapshotBeforeUpdate的返回值。
- 同样,在每次更新之后都会调用,所以使用
8. componentWillUnmount()
- 调用时期
- 组件被卸载的时候调用
- 说明
- 一般在
componentDidMount()里面注册的事件需要在这里删除,如:document.addEventListener('click', () => {}); - 处理一些必要的清理操作,比如无效的
timer、interval,或者取消网络请求,或者清理任何在componentDidMount()中创建的 DOM 元素
- 一般在
三个带
will的生命周期官方已不再推荐
- componentWillMount()
- componentWillReceiveProps(nextProps)
- componentWillUpdate(nextProps, nextState)
React v16.3.0 新增生命周期
1. static getDerivedStateFromProps(props, state)
- 调用时期
- 初始化和更新阶段
- 说明
- 根据父组件传来的
props按需更新自己的state - 返回一个对象,就是要更新的
state项(只会覆盖同名属性,不会全部重写),如果是null则不更新
- 根据父组件传来的
2. getSnapshotBeforeUpdate(prevProps, prevState)
- 调用时期
- 组件即将挂载时调用,甚至比
render晚
- 组件即将挂载时调用,甚至比
- 说明
getSnapshotBeforeUpdate生命周期钩子返回的值会被componentDidUpdate的第三个参数接收,我们可以利用这个通道保存一些不需要持久化的状态,用完即可舍弃。
3. componentDidCatch(error, info)
- 调用时期
- 捕获到错误
- 说明
- 定制一个只有
componentDidCatch生命周期钩子的ErrorBoundary组件,它只做一件事:如果捕获到错误,则显示错误提示,如果没有捕获到错误,则显示子组件。 详情
- 定制一个只有
生命周期
前面提到,生命周期总结起来只有三个过程:
- 挂载
- 更新
- 卸载
挂载和卸载只执行一次,更新则执行多次。
一个完整的生命周期会以此调用如下钩子
挂载
- constructor
- componentWillMount
- render
- componentDidMount
更新
- componentWillReceiveProps(组件传入新的 props 或父组件重新渲染时才触发)
- shouldComponentUpdate
- componentWillUpdate
- render
- componentDidUpdate
参考: