react生命周期
生命周期
初始化阶段
- constructor
- 在组件挂载之前执行,调用super(props),用来将父组件传来的props绑定到这个类中,使用this.props将会得到。
- 定义状态
- 状态初始化也可以有父组件传递过来的属性来进行赋值
- static getDerivedStateFromProps ( nextProps,prevState ) {}
- 在组件实例化后,和接受新的props后被调用。他必须返回一个对象来更新状态,或者返回 null表示新的props不需要任何state的更新。
- componentWillMount () {} 组件即将挂载
- 数据请求
- 将请求来的数据赋值给当前组件的状态
- render 函数
- 当他被调用时,他将计算this.props和this.state,返回一个类型
- componentDidMount
- 组件装载结束,将VDOM 渲染成了真实DOM
- 操作真实DOM( 第三方实例化 )
- 数据请求 ( 阿里用 )
更新阶段
props或state的改变可能会引起组件的更新,组件重新渲染的过程中会调用以下方法:
1.componentWillReceiveProps() / UNSAFE_componentWillReceiveProps()
-
官方建议使用getDerivedStateFromProps函数代替componentWillReceiveProps。当组件 挂载后,接收到新的props后会被调用。如果需要更新state来响应props的更改,则可以进行 this.props和nextProps的比较,并在此方法中使用this.setState()。
-
如果父组件会让这个组件重新渲染,即使props没有改变,也会调用这个方法。
-
React不会在组件初始化props时调用这个方法。调用this.setState也不会触发。
2.static getDerivedStateFromProps()
在渲染新的props或state前,shouldComponentUpdate会被调用。默认为true。这个方法不会在初始化时被调用,也不会在forceUpdate()时被调用。返回false不会阻止子组件在state更改时重新渲染。
3.shouldComponentUpdate()
-
调用shouldComponentUpdate使React知道,组件的输出是否受state和props的影响。默认每个状态的更改都会重新渲染,大多数情况下应该保持这个默认行为。
-
在渲染新的props或state前,shouldComponentUpdate会被调用。默认为true。这个方法不会在初始化时被调用,也不会在forceUpdate()时被调用。返回false不会阻止子组件在state更改时重新渲染。
-
如果shouldComponentUpdate()返回false,componentWillUpdate,render和componentDidUpdate不会被调用。
-
官方并不建议在shouldComponentUpdate()中进行深度查询或使用JSON.stringify(),他效率非常低,并且损伤性能。
4.componentWillUpdate() / UNSAFE_componentWillUpdate()
-
在渲染新的state或props时,UNSAFE_componentWillUpdate会被调用,将此作为在更新发生之前进行准备的机会。这个方法不会在初始化时被调用。
-
不能在这里使用this.setState(),也不能做会触发视图更新的操作。如果需要更新state或props,调用getDerivedStateFromProps。
5.render()
6.getSnapshotBeforeUpdate()
- 在react render()后的输出被渲染到DOM之前被调用。它使您的组件能够在它们被潜在更改之前捕获当前值(如滚动位置)。这个生命周期返回的任何值都将作为参数传递给componentDidUpdate()
7.componentDidUpdate()
-
在更新发生后立即调用componentDidUpdate()。此方法不用于初始渲染。当组件更新时,将此作为一个机会来操作DOM。只要您将当前的props与以前的props进行比较(例如,如果props没有改变,则可能不需要网络请求),这也是做网络请求的好地方。
-
如果组件实现getSnapshotBeforeUpdate()生命周期,则它返回的值将作为第三个“快照”参数传递给componentDidUpdate()。否则,这个参数是undefined。
import React, { Component,Fragment } from 'react'
class Life extends Component{
constructor ( props ) { //props是由父级传来的
super( props )
this.state = {
count: 0,
f: props.name
}
console.log(' 01- constructor ')
}
// static getDerivedStateFromProps ( nextProps,prevState) { //未来版本的componentWillMount
// console.log( 'nextprops', nextProps )
// console.log( 'prevState',prevState )
// console.log( '02-getDerivedStateFromProps' )
// return null
// }
// componentWillMount () { // vue created + beforeMount 未来版本淘汰
// console.log( '03-componentWillMount' )
// }
countHandler = () => {
this.setState({
count: 1000
})
}
render () {
console.log(' 04-render~~~~~~~~~ ')
let { name } = this.props
let { count } = this.state
return (
<Fragment>
<h3> 生命周期 - 初始化 - 5个钩子函数 </h3>
<p> { name } </p>
<hr/>
<button onClick = { this.countHandler }> 更改自己的状态count </button>
<p> { count } </p>
</Fragment>
)
}
componentDidMount () {
console.log('05-componentWillMount')
}
// --------------------------- 更新阶段 -------------------------------
// componentWillReceiveProps ( nextProps ) { //当组件身上属性更改时触发 ,里面有个参数,nextProps
//状态改变也没啥变化
// console.log( '更新阶段--componentWillReceiveProps')
// }
shouldComponentUpdate () { // 决定当props或是state更改时,组件要不要渲染, 默认返回时true
console.log(' 更新阶段 -- shouldComponentUpdate ')
return true
}
// UNSAFE_componentWillUpdate () { //组件即将更新
// console.log('更新阶段-componentWillUpdate')
// }
getSnapshotBeforeUpdate () {
console.log('更新阶段-getSnapshotBeforeUpdate')
return 'xiaojunjun '
}
componentDidUpdate ( prevprops,prvestate,snapshot) {
console.log(prevprops,prvestate,snapshot)
console.log( '更新阶段-componentDidUpdate' )
}
}
export default Life
销毁阶段
componentWillUnmount () {
console.log('销毁阶段--componentWillUnmount') // 善后
}
<button onClick = { this.destroy }> 销毁 </button>
{ !flag||<Life name = { name }></Life>}
注意:
static getDerivedStateFromProps vs componentWillMount
- 他们功能是一致的,但是 前一个是未来版本使用, 后一个 未来版本将会被淘汰,但是现低版本用的都是它
错误处理
生命周期第四个阶段 – 错误处理
例子
import React from 'react'
class Error extends React.Component {
constructor(props) {
super(props);
this.state = { error: false };
}
componentDidCatch(error, info) {
console.log('错误处理-componentDidCatch')
this.setState({ error, info });
}
errorHandle = () => {
this.setState({
error: true
})
}
render() {
if (this.state.error) {
return (
<div>
<p> 报错了 </p>
{
console.log(new Error("YOLO"))
}
</div>
)
}
return (
<div>
<button onClick = { this.errorHandle }>
抛出错误
</button>
</div>
);
}
}
export default Error