zoukankan      html  css  js  c++  java
  • 图解React组件生命周期

    一、组件生命周期

    每个react类组件都包含“生命周期方法”(function组件是没有生命周期方法的),你可以重写这些方法,以便于在运行过程中特定的阶段执行这些方法。在接下来的文章中,生命周期方法的书写会遵照如下规则,以方便大家理解。

    1、加粗生命周期方法表示常用的生命周期方法,开发中会经常使用到。

    2、未加粗的生命周期方法表示罕见的生命周期方法,开发中很少会用到。

    3、画中横线的生命周期方法表示即将过期的方法,开发中应避免使用。

    4、若一定要使用即将失效的生命周期方法,可以参考官方文档。

    首先通过一幅图来看下react组建的全部生命周期(version: ^16.4,之前的版本会略有区别)。

    二、挂载

    当组件实例被创建并插入 DOM 中时,被称为组件挂载,其生命周期调用顺序如下:

    • constructor()
      static getDerivedStateFromProps()
      UNSAFE_componentWillMount()
      render()
      componentDidMount()

    1. constructor(props)  

    在 React 组件挂载之前,会调用它的构造函数。在为 React.Component 子类实现构造函数时,应在其他语句之前前调用super(props)。否则,this.props在构造函数中可能会出现未定义的 bug。

    通常,在 React 中,构造函数仅用于以下两种情况:

    1. 通过给this.state赋值对象来初始化内部 state。
    2. 为事件处理函数绑定实例

    如果不初始化 state 且不进行方法绑定,则不需要为 React 组件实现构造函数。

     

    2. static getDerivedStateFromProps(props, state)  

    getDerivedStateFromProps会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。它应返回一个对象来更新 state,如果返回 null 则不更新任何内容。此方法无权访问组件实例。如果你需要,可以通过提取组件 props 的纯函数及 class 之外的状态,在getDerivedStateFromProps()和其他 class 方法之间重用代码。

    3. render()  

    render()方法是 class 组件中唯一必须实现的方法。该函数应该为纯函数,这意味着在不修改组件 state 的情况下,每次调用时都返回相同的结果,并且它不会直接与浏览器交互。

    如需与浏览器进行交互,请在componentDidMount()或其他生命周期方法中执行你的操作。保持render()为纯函数,可以使组件更容易思考。

    4. componentDidMount()  

    componentDidMount()会在组件挂载后(插入 DOM 树中)立即调用。依赖于 DOM 节点的初始化应该放在这里。如需通过网络请求获取数据,此处是实例化请求的好地方。

    这个方法是比较适合添加订阅的地方。如果添加了订阅,请不要忘记在componentWillUnmount()里取消订阅。

    三、更新

    当组件的 props 或 state 发生变化时会触发更新。组件更新的生命周期调用顺序如下:

    • static getDerivedStateFromProps()
      shouldComponentUpdate()
      UNSAFE_componentWillReceiveProps()
      UNSAFE_componentWillUpdate()
      render()
      getSnapshotBeforeUpdate()
      componentDidUpdate()

    1、shouldComponentUpdate(nextProps, nextState)  

    该方法是控制组件是否应该被更新。如果方法返回false则后续的生命周期方法将全部被跳过,该方法会接收nextProps 和nextState,可以通过比较this.props 和nextProps、this.state和nextState来决定是否要重新渲染组件,来对组件进行性能优化。你应该考虑使用内置的 PureComponent 组件,而不是手动编写 shouldComponentUpdate()

    官网中不建议在 shouldComponentUpdate() 中进行深层比较或使用 jsON.stringify()。这样非常影响效率,且会损害性能。

    2、getSnapshotBeforeUpdate(prevProps, prevState)  

    getSnapshotBeforeUpdate() 在最近一次渲染输出(提交到 DOM 节点)之前调用。它使得组件能在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置)。此生命周期的任何返回值将作为参数传递给 componentDidUpdate()。

    3、componentDidUpdate(prevProps, prevState, snapshot)  

    componentDidUpdate() 会在更新后会被立即调用。首次渲染不会执行此方法。

    当组件更新后,可以在此处对 DOM 进行操作。如果你对更新前后的 props 进行了比较,也可以选择在此处进行网络请求。(例如,当 props 未发生变化时,则不会执行网络请求)

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

    你也可以在 componentDidUpdate() 中直接调用 setState(),但请注意它必须被包裹在一个条件语句里,正如上述的例子那样进行处理,否则会导致死循环。

    四、卸载

    componentWillUnmount()

    componentWillUnmount()会在组件卸载及销毁之前直接调用。在此方法中执行必要的清理操作,例如,清除 timer,取消网络请求或清除在componentDidMount()中创建的订阅等。

    五、错误处理

    static getDerivedStateFromError()

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

    此生命周期会在后代组件抛出错误后被调用。 它将抛出的错误作为参数,并返回一个值以更新 state,你可以通过判断state中的某个字段,来显示降级UI

    componentDidCatch()

    此生命周期在后代组件抛出错误后被调用,可以用于日志记录。 它接收两个参数:

    1. error—— 抛出的错误。
    2. info—— 带有componentStack key 的对象
    componentDidCatch(error, info) {
      logToMyService(info.componentStack);
    }

    豌豆资源搜索网站https://55wd.com 广州vi设计公司http://www.maiqicn.com

  • 相关阅读:
    Day042---浮动 背景图设置 相对定位绝对定位
    day049--jQuery文档操作示例
    iOS 8 Extensions
    《驾驭Core Data》 第三章 数据建模
    《驾驭Core Data》 第二章 Core Data入门
    《驾驭Core Data》 第一章 Core Data概述
    iOS代码工具箱再续
    PS图层混合模式实例详解
    Core Animation编程指南
    iOS应用开发最佳实践系列一:编写高质量的Objective-C代码
  • 原文地址:https://www.cnblogs.com/qianxiaox/p/13712353.html
Copyright © 2011-2022 走看看