React-生命周期

27 篇文章 0 订阅
5 篇文章 0 订阅

React-生命周期

组件生命周期的三个阶段

  • Mounting(加载阶段)
  • Updating(更新阶段)
  • Unmounting(卸载阶段)

先来介绍一个生命周期的定义:

  • componentWillMount(){}
// Mounting  安装阶段 
// 在客户端和服务器上,在初始渲染发生之前立即调用一次 如果在这个方法中调用setState,
// render()将看到更新的状态,并且只会执行一次,尽管状态改变。
  • componentDidMount(){}
// Mounting  安装阶段 
// 调用一次,只在客户端(不在服务器上),在初始渲染发生后立即
// 子组件的componentDidMount()方法在父组件的componentDidMount()方法之前被调用
// setTimeout  setInterval   AJAX 在此之行,强烈建议

【注】:componentWillMountcomponentDidMount这两个生命周期函数,只在页面刷新时执行一次,而render函数是只要有state和props变化就会执行,这个初学者一定要注意。

  • componentWillReceiveProps(nextProps){}
// Updating 更新阶段
// 在组件接收新props时调用。初始渲染不调用此方法。
// 老的props可以用this.props  新值就用nextProps查看
// 在此函数中调用this.setState()不会触发附加的渲染。
  • shouldComponentUpdate(nextProps, nextState){}
// Updating 更新阶段
// 当正在接收新的props或状态时,在渲染之前调用。
// 此方法必须返回false or true 否则报错  true则渲染,false则不渲染!在此声明周期中可以考虑是否需要进行渲染!避免不必要的性能浪费
// 如果shouldComponentUpdate返回false,那么render()将被完全跳过,直到下一个状态改变。此外,不会调用componentWillUpdate和componentDidUpdate。
// 默认返回true
// 如果性能是一个瓶颈,特别是有几十个或几百个组件,请使用shouldComponentUpdate来加快您的应用程序。
// return true or false

//----------------------------------------------------------------------------------------------------------------
//生命周期性能优化
//例如:input框输入值

 shouldComponentUpdate(nextProps,nextState){
        if (nextProps.content!==this.props.content) {
            return true
    }else{
        return false
    }
  • componentWillUpdate(nextProps, nextState){}
// Updating 更新阶段
// 当正在接收新的props或state时立即调用。初始渲染不调用此方法
// 您不能在此方法中使用this.setState()。如果您需要更新state以响应prop更改,请改用componentWillReceiveProps
  • componentDidUpdate(nextProps, nextState){}
// Updating  更新阶段
// 在组件的更新刷新到DOM后立即调用。初始渲染不调用此方法。
// 当组件已更新时,使用此操作作为DOM操作的机会
  • componentWillUnmount(){}
// Unmounting  卸载阶段
// 在组件从DOM卸载之前立即调用。
// 在此方法中执行任何必要的清理,例如使计时器无效或清除在componentDidMount中创建的任何DOM元素。clearInterval or destroy 

在 V16 版本中引入了 Fiber 机制。这个机制一定程度上的影响了部分生命周期的调用,并且也引入了新的 2 个 API 来解决问题

在之前的版本中,如果你拥有一个很复杂的复合组件,然后改动了最上层组件的 state,那么调用栈可能会很长,调用栈过长,再加上中间进行了复杂的操作,就可能导致长时间阻塞主线程,带来不好的用户体验。Fiber 就是为了解决该问题而生。

Fiber 本质上是一个虚拟的堆栈帧,新的调度器会按照优先级自由调度这些帧,从而将之前的同步渲染改成了异步渲染,在不影响体验的情况下去分段计算更新。

对于如何区别优先级,React 有自己的一套逻辑。对于动画这种实时性很高的东西,也就是 16 ms 必须渲染一次保证不卡顿的情况下,React 会每 16 ms(以内) 暂停一下更新,返回来继续渲染动画。

对于异步渲染,现在渲染有两个阶段:reconciliation 和 commit 。前者过程是可以打断的,后者不能暂停,会一直更新界面直到完成。

Reconciliation(调和) 阶段
==》调和过程:即React更新中对DOM找不同的过程,通常对比两个N个节点的树形结构的算法,

  • componentWillMount
  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate

因为 Reconciliation 阶段是可以被打断的,所以 Reconciliation 阶段会执行的生命周期函数就可能会出现调用多次的情况,从而引起 Bug。由此对于 Reconciliation 阶段调用的几个函数,除了 shouldComponentUpdate 以外,其他都应该避免去使用,并且 V16 中也引入了新的 API 来解决这个问题。

Commit 阶段

  • componentDidMount
  • componentDidUpdate
  • componentWillUnmount

getDerivedStateFromProps 用于替换 componentWillReceiveProps ,该函数会在初始化和 update被调用

static getDerivedStateFromProps(nextProps, prevState) {
    const {type} = nextProps;
    // 当传入的type发生变化的时候,更新state
    if (type !== prevState.type) {
        return {
            type,
        };
    }
    // 否则,对于state不进行任何操作
    return null;
}

  • 无条件的根据 prop 来更新内部 state,也就是只要有传入 prop 值, 就更新 state
  • 只有 prop 值 或 state 值不同时才更新 state 值。
class ExampleComponent extends React.Component {
  // Initialize state in constructor,
  // Or with a property initializer.
  state = {};

  static getDerivedStateFromProps(nextProps, prevState) {
    if (prevState.someMirroredValue !== nextProps.someValue) {
      return {
        derivedData: computeDerivedState(nextProps),
        someMirroredValue: nextProps.someValue
      };
    }

    // Return null to indicate no change to state.
    return null;
  }
}

getSnapshotBeforeUpdate 用于替换 componentWillUpdate ,该函数会在 update DOM 更新前被调用,用于读取最新的 DOM 数据。

getSnapshotBeforeUpdate ----------更新前获取快照


componentWillReceiveProps(nextProps){}

  • 在此函数中调用this.setState()不会触发附加的渲染。

componentWillUpdate(nextProps, nextState){}

  • // 您不能在此方法中使用this.setState()。如果您需要更新state以响应prop更改,请改用componentWillReceiveProps

    React16新的生命周期弃用了componentWillMount、componentWillReceivePorps,componentWillUpdate
    新增了getDerivedStateFromProps、getSnapshotBeforeUpdate来代替弃用的三个钩子函数(componentWillMount、componentWillReceivePorps,componentWillUpdate)
    React16并没有删除这三个钩子函数,但是不能和新增的钩子函数(getDerivedStateFromProps、getSnapshotBeforeUpdate)混用,React17将会删除componentWillMount、componentWillReceivePorps,componentWillUpdate
    新增了对错误的处理(componentDidCatch)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值