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

  1. 他们功能是一致的,但是 前一个是未来版本使用, 后一个 未来版本将会被淘汰,但是现低版本用的都是它
错误处理

生命周期第四个阶段 – 错误处理

例子

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
生命周期图

react生命周期