一、废除的生命周期
官网文档指出使用这些生命周期的代码会在未来版本的react中更容易产生bug,尤其是对于异步渲染的版本
由于未来采用异步渲染机制,所以即将在17版本中去掉的生命周期钩子函数
componentWillMount
componentWillRecieveProps
componentWIllUpdate
二、新增的生命周期
static getDerivedStateFromProps(nextProps, prevState) {}
用于替换componentWillReceiveProps,可以用来控制 props 更新 state 的过程;它返回一个对象表示新的 state;如果不需要更新,返回 null 即可
在每次渲染之前都会调用,不管初始挂载还是后面的更新都会调用,这一点和componentWillReceiveProps不同(只有当父组件造成重新渲染时才调用
简单的理解就说从props中获取state,这个生命周期的功能实际上就是将传入的props映射到state上面
getDerivedStateFromProps是一个静态函数,也就是这个函数不能通过this访问到class的属性,也并不推荐直接访问属性。而是应该通过参数提供的nextProps以及prevState来进行判断,根据新传入的props来映射到state
如果props传入的内容不需要影响到你的state,那么就需要返回一个null,这个返回值是必须的,所以尽量将其写到函数的末尾
getSnapshotBeforeUpdate() {}
在最近的更改被提交到DOM元素前,使得组件可以在更改之前获得当前值,此生命周期返回的任意值都会传给componentDidUpdate()。
用于替换 componentWillUpdate,该函数会在update后 DOM 更新前被调用,用于读取最新的 DOM 数据,返回值将作为 componentDidUpdate 的第三个参数
在最新的渲染数据提交给DOM前会立即调用,它让你在组件的数据可能要改变之前获取他们
componendDidCatch(error, info)
如果一个组件定义了componentDidCatch生命周期,则他将成为一个错误边界(错误边界会捕捉渲染期间、在生命周期方法中和在它们之下整棵树的构造函数中的错误,
就像使用了try catch,不会将错误直接抛出了,保证应用的可用性)
三、下面来看看实际应用场景分析:
/*
* @Descripttion: react17 生命周期测试
* @version:
* @Author: lhl
* @Date: 2021-03-04 14:51:12
* @LastEditors: lhl
* @LastEditTime: 2021-03-26 18:46:49
*/
import React, { Component } from 'react'
import PropTypes from 'prop-types' // prop代表父组件传递过来的值,types代表类型 简单来说就是用来校验父组件传递过来值的类型
// 类组件
/*
1.挂载时顺序
constructor() --> static getDerivedStateFromProps(props, state) --> render() --> componentDidMount()
2.更新时顺序
static getDerivedStateFromProps(props, state) --> shouldComponentUpdate() --> render() -->
static getSnapshotBeforeUpdate(prevProps, prevState) --> componentDidUpdate()
3.卸载 (比如页面切换)
componentWillUnmount()
在 Fiber 机制下,render 阶段是允许暂停、终止和重启的。废弃的生命周期钩子函数,它们都处于render阶段,都可能被重复执行
在 componentWillReceiveProps 和 componentWillUpdate 里滥用 setState 导致重复渲染死循环的
forceUpdate(callback) - 组件强制更新,会跳过shouldComponentUpdate
*/
export default class LifeCycle extends Component {
// constructor()用来做一些组件的初始化工作,如定义this.state的初始内容 为事件处理函数绑定实例
constructor(props){
// super(props)用来调用基类的构造方法( constructor() ), 也将父组件的props注入给子组件,供子组件读取(组件中props只读不可变,state可变)
super(props)
this.state = {
count: 0
}
console.log('constructor')
}
// static propTypes = {
// prop: PropTypes // react里的defaultProps来设置默认的props值
// }
static getDerivedStateFromProps(props, state){
console.log(props, state,'getDerivedStateFromProps')
return true
}
componentDidMount(){
console.log('componentDidMount')
}
// 根据更新后的state或props判断是否重新渲染DOM,返回值为布尔值,常用来性能优化
/**
* 判断是否需要更新视图,执行后面的render方法
* 1. 如果返回 false ,则不需要执行后面的render方法,视图也不会改变
* 2. 返回true, 需要执行render方法,视图也会对应的改变
*/
// 下一个和当前状态对比 nextState === this.state.xxx 没有变化就 return false 否则 true
shouldComponentUpdate(nextProps, nextState){
console.log(nextProps, nextState, 'shouldComponentUpdate')
return true
}
// 该函数会在update后 DOM 更新前被调用,用于读取最新的 DOM 数据,返回值将作为 componentDidUpdate 的第三个参数
getSnapshotBeforeUpdate(prevProps, prevState){
console.log(prevProps, prevState,'getSnapshotBeforeUpdate')
return true
}
// state或props更新后调用
componentDidUpdate(props, state, snapshot){
console.log(props, state, snapshot,'componentDidUpdate')
}
// 组件销毁或卸载时调用
componentWillUnmount(){
console.log('componentWillUnmount')
}
// 错误处理
// 后代组件跑出错误时调用,并返回一个值以更新state
static getDerivedStateFromError(callback){
console.log(callback)
}
// 后代组件抛出错误后调用,参数info包含有关组件错误的栈信息
componentDidCatch(error, info){
console.log(error, info)
}
handleChange = () => {
this.setState({
count: 12
})
}
// 渲染React组件 PureComponet 和 shouldComponentUpdate 处理渲染性能优化问题
// 初始化
// setState()在任何情况下都会导致组件的重新渲染,即使state未发生变化
// 只要父组件重新渲染了,那么子组件就会重新渲染
render() {
console.log('render')
const { count } = this.state
return (
<div>
<h1>react 17 生命周期</h1>
<button onClick={this.handleChange}>更改状态{count}</button>
</div>
)
}
}
LifeCycle.propTypes = {
name: PropTypes.string
};
未经允许,请勿随意转载!!谢谢合作!!!