React的生命周期

React 组件的生命周期

  • React中组件有生命周期,也就是说也有很多钩子函数供我们使用, 组件的生命周期,我们会分为四个阶段,初始化、运行中、销毁、错误处理(16.3之后) ( 共12个钩子函数 )

  • 注意: 生命周期钩子函数一定不要写成箭头函数

初始化

在组件初始化阶段会执行 5个钩子函数【 1个将来会使用 】

1. constructor( props )

  constructor ( props ) {
    /* 
      作用: 初始化属性 和  定义状态 
        * 初始化属性: 将父组件绑定在子组件身上的属性获取到 , 
                    然后  通过super继承给子组件 的 porps属性上 
        * 定义状态
    */
    super( props )
    // console.log( props )
    // this.props = props 
    this.state = {
      msg: 'Hello World!' 
    }
    console.log('1-constructor')
  }

2. static getDerivedStateFromProps(nextProps, prevState) ---- 将来会使用 17.x

 static getDerivedStateFromProps(nextProps, prevState) {//(使用之后componentWillMount() 不能用)
    console.log(nextProps,prevState)
    console.log('getDerivedStateFromProps')
    fetch('/data.json')
    .then( res => res.json())
    .then( data => {
      console.log( data )  // 可以数据请求
    })
    .catch( error => {
      if( error ) throw error
    })
    return {  //必须返回一个结果
      msg: '你好吗'
    }
  }

3. componentWillMount() / UNSAFE_componentWillMount()

  componentWillMount () {
    /* 
      作用: 组件即将挂载
        * 做组件即将挂载的准备工作
        * 这个钩子可以进行数据的同步修改
        * setState在这个中是可以起作用的
        * 16.x 版本使用
        * 数据可以获取到
        * 真实dom没有拿到
        * 类似  vue   create + beforeMount
        * 数据请求 + 数据修改
        * 可能会产生副作用和其他的订阅
          1. 副作用: 计时器 、 滚轮事件

      项目: 
        数据请求 + 数据修改

    */
    console.log( this.state.msg )
    console.log( document.querySelectorAll('h3'))
    console.log( document.querySelectorAll('p'))
    console.log('2-componentWillMount')

    fetch('/data.json')
      .then( res => res.json())
      .then( data => {
        this.setState({
          msg: data.name
        })
      })
      .catch( error => {
        if( error ) throw error
      })

  }



  UNSAFE_componentWillMount () {
    /* 
      * 这个钩子可以进行数据的同步修改
      * setState在这个中是可以起作用的 
      * 这是旧(16.x之前)的钩子【 不推荐使用 】
    */
    this.setState({
      msg: '蓝球运动'
    })
  }

4.render()

render()方法是必需的


render () {
    /* 
      作用: 
        jsx  -> vdom  js对象模型
    */
    console.log('4-render')
    const { msg } = this.state
    return (
      <Fragment>
        <h3> 生命周期 </h3>
        <p> { msg } </p>
      </Fragment>
    )
}


5.componentDidMount()

  componentDidMount () {
    /* 
      作用: 组件挂载结束
        * 数据拿取到
        * 真实dom能不能拿到呢? 能
        * 数据请求 + 数据修改
        * 真实dom操作 【 第三方库的实例化 】
    */
   fetch('/data.json')
    .then( res => res.json())
    .then( data => {
        this.setState({
        msg: data.name
        })
    })
    .catch( error => {
        if( error ) throw error
    })

   document.querySelector('h3').style.background = 'red'
   console.log( '4-componentDidMount',document.querySelectorAll('h3'))
   console.log('4-componentDidMount', document.querySelectorAll('p'))
   console.log('4-componentDidMount')
  }

运行中( 更新阶段 )

props 或 state 的改变可能会引起组件的更新,组件重新渲染的过程中会调用以下方法

共有7个钩子函数( 4个主要 1个是复用render() 2个将来会使用(17.x) )

1.componentWillReceiveProps() / UNSAFE_componentWillReceiveProps()

  componentWillReceiveProps ( nextProps ) {
    /* 
      触发: props改变触发 
        * nextProps是改变后的值
        * this.props.xxx 是改变前的值
      作用: 检测项目中的一些变化情况 
        * React 路由监听
      nextProps.xxx === this.props.xxx  ? 证明某一个属性( xxx )没有改变
      使用场景: 检测到项目中某一个按钮是否触发: 点击注册自动跳转登录
    */
    console.log( this.props.name ) // 旧值
    console.log('nextProps',nextProps) // nextProps是新值
    console.log('props改变触发-componentWillReceiveProps')
  }

2.static getDerivedStateFromProps() ----将来会使用(17.x) 复用-初始化中

  static getDerivedStateFromProps () {
    console.log('getDerivedStateFromProps')
    return {
      msg: '你好吗'
    }
  } 

3.shouldComponentUpdate() // react性能优化第二方案

    shouldComponentUpdate () {
    /* 
      作用: 决定组件是否要更新 
      必须要有返回值,默认返回值是true
    
    */
    // return true
    // return false
    console.log('shouldComponentUpdate');
    return true;
  }

4.componentWillUpdate() / UNSAFE_componentWillUpdate()-- 带有UNSAFE这个的都是旧版本(16.x以前)

     componentWillUpdate () {
    /* 
      组件即将更新
      为整个更新,做准备工作
      类似于vue  beforeUpdate
      拿到的是更新前的数据 ,可以获得更新后的真实dom

      项目中: 
          这个钩子项目中我们一般不去使用它

      问题: 如果我们在这个钩子中使用  setState ,会发生什么?

      解答: 会发生死循环


      注意: 不要在这个钩子中使用  setState 
    */

    console.log('this.props.name ',this.props.name)
    console.log('真实dom',document.querySelectorAll('p'))
    console.log('componentWillUpdate')
  }

5.render() 会在更新过程中在执行一次
6.getSnapshotBeforeUpdate() ---- 将来会使用(17.x)

    getSnapshotBeforeUpdate () {
        // 获得更新前的快照
        console.log('getSnapshotBeforeUpdate')
        return '组件更新了'
    }

7.componentDidUpdate()

    componentDidUpdate ( a,b,c ) {
        console.log( 'a',a) // 更新前的属性
        console.log( 'b',b) // 更新前的状态
        console.log( 'c',c) // getSnapshotBeforeUpdate 的返回值
        /* 
        * 组件更新结束
            * 可以拿取到更新之后的数据
            * 可以获得更新之后的真实DOM
        * 项目:
            * 操作真实DOM【 第三方库的实例化 】  
        */
        console.log('this.props.name ',this.props.name)
        console.log('真实dom',document.querySelectorAll('p'))
        console.log('componentDidUpdate')
    }

卸载阶段( 销毁 )

componentWillUnmount()

import React,{ Component,Fragment } from 'react'
import ReactDOM from 'react-dom'

class LifeCircle extends Component{

  constructor () {
    super()
 
  }

  componentWillMount () {
    /* 
      犯错高发地带
    */
    this.timer = setInterval(() => {
      console.log('hello');
    },1000)
  }

  destory = () => {
    /* 
      React组件内部销毁
        * unmountComponentAtNode( Node ) Node是整个项目最大的容器
          ReactDOM.unmountComponentAtNode( document.getElementById('root') ) 
        * 这个方法可以删除组件的DOM外壳
      
      不推荐大家使用
    */

    ReactDOM.unmountComponentAtNode( document.getElementById('root') )

  }

    render () {
        return (
        <Fragment>
            <h3> 生命周期 </h3>
            <button onClick = { this.destory }> 内部销毁 </button>
        
        </Fragment>
        )
    }

    componentWillUnmount () {
        /* 
        * 组件卸载时触发
            * 做善后
            * 计时器、滚轮事件‘第三方库实例化出来的实例
        */
    clearInterval( this.timer )
        console.log('componentWillUnmount')
    }

}

export default LifeCircle

错误处理

componentDidCatch() — 16.3版本之后才有的

import React,{ Component,Fragment,logComponentStackToMyService } from 'react'
import ReactDOM from 'react-dom'

import Child from './Child'  //这里是引入一个外部子组件

class LifeCircle extends Component{

  constructor () {
    super()
    this.state = {
      flag: false
    }
  }

  static getDerivedStateFromError(error) {
    // 更新 state 使下一次渲染可以显示降级 UI
    console.log('getDerivedStateFromError')
    return { flag: true };
  }

  componentDidCatch(error, info) {
    // "组件堆栈" 例子:
    //   in ComponentThatThrows (created by App)
    //   in ErrorBoundary (created by App)
    //   in div (created by App)
    //   in App
    logComponentStackToMyService(info.componentStack);
  }


  render () {
    if( this.state.flag ){
      return <h1>Something went wrong.</h1>;
    }
    return (
      <Fragment>
        <h3> 生命周期 </h3>
        <hr/>
        <Child/>
      </Fragment>
    )
  }

}

export default LifeCircle

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值