react生命周期

React生命周期

react生命周期可以从广义分为三个阶段,即挂载渲染卸载。在这个过程中提供有很多生命周期钩子函数,在不同生命周期可以被调用。

生命周期官方结构图

img

挂载过程

当组件实力被创建并且被插入DOM中时,生命周期如下:

  • constructor() 构造函数 一般不可以调用setState方法,只绑定初始状态

    • 组件挂载之前会调用构造函数

    • 为子类实现构造函数时候,在构造函数内调用super(props)

      constructor(props) {
          super(props);
      }
      
    • 通过在构造函数内使用this.state对象初始化内部的state

    • 在给state赋值初始值时候避免将props赋值给state,这是一个常见的错误

  • static getDerivedStateFromProps(props,state)props中获取衍生的状态

    • 调用render方法之前调用
    • 并且在初始化、更新阶段都会被调用
    • 返回一个对象更新state,如果返回null则不更新
  • componentWillMount() 组件即将挂载 在新的生命周期中已经废除(谨慎使用)

  • render() 渲染函数

  • componentDidMount() 组件挂载完成后,立即调用

下述方法即将过时谨慎使用:

  • UNSAFE_componentWillMount()

更新过程

当组件的props或者state发生变化时,组件生命周期如下:

  • compontentWillReceiveProps(nextProps) 组件即将接收props阶段

  • static getDerivedStateFromProps(props,state) 获取新的状态

  • shouldCompontentUpdate(nextProps,nextState) 判断是否应该更新

    • 会在组件渲染之前被调用,返回值默认为true
    • 首次渲染使用forceUpdate()时不会调用该方法
    • 返回值 true更新false不更新
    • 默认state每次发生变化组件都会重新渲染
    • 如果考虑性能优化可以使用内置的PureComponent组件,PureComponent会对propsstate进行浅层次的比较,并且减少不必要的更新
    • 如果shouldComponentUpdate()返回false,将不会调用compoentWillUpdate()render()componentDidUpdate(),并且返回false仍然可能导致组件重新渲染
  • componentWillUpdate(nextProps,nextState)

    • 当组件接收到新的propsstate时,会在渲染之前调用
    • 初始渲染不会调用
    • 不能在此方法中调用this.setState,也不能进行其他操作出发组件更新
  • render()

  • getSnapshotBeforeUpdate(prevProps,prevState) 获取快照

    • 他的返回值将作为componentDidUpdate()的第三个参数
    • 否则此参数为undefined
  • compontentDidUpdate(pervProps,prevState,snapshot)

    • 会在更新结束之后立即被调用

    • 首次渲染不会执行

    • 当组件更新后可以对DOM进行操作

    • 可以在该钩子函数中调用setState,但必须包裹在一个条件语句中不然会导致死循环

      componentDidUpdate(prevProps) {
        // 典型用法(不要忘记比较 props):
        if (this.props.userID !== prevProps.userID) {
          this.fetchData(this.props.userID);
        }
      }
      

下述方法即将过时,在新代码中应该避免使用:

  • UNSAFE_componentWillUpdate(nextProps,nextState)
  • UNSAFE_compontentWillReceiveProps(nextProps)

卸载过程

当组件从DOM中移除时,会调用以下钩子函数:

  • componentWillUnmount()
    • 会在组件卸载之前调用
    • 可以用作清理操作,例如清除timer、解绑事件,取消网络请求或者清除在componentDidMount()中创建的订阅
    • 不能在此钩子函数中调用setState,因为组件永远不会被重新渲染

错误处理

当渲染,生命周期或者构造函数中抛出错误时,会调用以下钩子函数:

  • static getDerivedStateFromError(error)

    • 后代组件抛出错误时候调用

    • 返回一个值更新state

      class ErrorBoundary extends React.Component {
        constructor(props) {
          super(props);
          this.state = { hasError: false };
        }
      
        static getDerivedStateFromError(error) {
          // 更新 state 使下一次渲染可以显降级 UI
          return { hasError: true };
        }
      
        render() {
          if (this.state.hasError) {
            // 你可以渲染任何自定义的降级  UI
            return <h1>Something went wrong.</h1>;
          }
      
          return this.props.children;
        }
      }
      
  • componentDidCatch(error, info)

    • 后代组件抛出错误时候调用

    • error 抛出的错误

    • info 带有componentStack key的对象,包含引发错误的错误栈信息

    • 允许支持副作用

      lass ErrorBoundary extends React.Component {
        constructor(props) {
          super(props);
          this.state = { hasError: false };
        }
      
        static getDerivedStateFromError(error) {
          // 更新 state 使下一次渲染可以显示降级 UI
          return { hasError: 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.hasError) {
            // 你可以渲染任何自定义的降级 UI
            return <h1>Something went wrong.</h1>;
          }
      
          return this.props.children;
        }
      }
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值