• React 生命周期


    每个组件都包含“生命周期方法”,你可以重写这些方法,以便于在运行过程中特定的阶段执行这些方法。

    你可以使用此  生命周期图谱  作为速查表。

    挂载 :

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

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

       static getDerivedStateFromProps() :(不常用)

           render() : 渲染页面,class组件中唯一必须实现的方法。

          componentDidMount()  :Dom 挂载完成

       注意:生命周期componentWillMount() 即将过时,项目中应避免使用他们:

                (在挂载之前被调用。它在 render() 之前调用,因此在此方法中同步调用 setState() 不会触发额外渲染。通常,我们建议使用 constructor() 来初始化 state。

                   避免在此方法中引入任何副作用或订阅。如遇此种情况,请改用 componentDidMount()

                    此方法是服务端渲染唯一会调用的生命周期函数。)

    更新 :

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

              static getDerive的StateFromProps()

              shouldComponentUpdate()

              render() : 渲染页面,class组件中唯一必须实现的方法。

              getSnapshotBeforeUpdate():

              componentDidUpdate():更新前

        注意:componentWillUpdate(nextprops, nextState) :此生命周期之前名为 componentWillUpdate。该名称将继续使用至 React 17。可以使用 rename-unsafe-lifecycles codemod 自动更新你的组件。

                componentWillReceiveProps():此生命周期之前名为 componentWillReceiveProps。该名称将继续使用至 React 17。可以使用 rename-unsafe-lifecycles codemod 自动更新你的组件

                即将过时,应避免使用。

     卸载 :当组件从DOM中移除时会调用如下方法:

              componentWillUnmount ()

     

     错误处理:当渲染过程中,生命周期或子组件的构造函数中抛出错误时会调用如下方法:

       static getDerivedStateFromError()

       componentDidCatch()

    详解:

    一、render():方法是class组件中唯一必须实现的方法。

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

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

         当render()函数被调用时,他会检查 this.props 和 this.state  的变化并返回以下类型之一:

            1.React 元素。通常通过 JSX 创建。例如,<div /> 会被 React 渲染为 DOM 节点,<MyComponent /> 会被 React 渲染为自定义组件,无论是 <div /> 还是 <MyComponent /> 均为 React 元素。

            2.数组或 fragments。 使得 render 方法可以返回多个元素。欲了解更多详细信息,请参阅 fragments 文档。

            3.  Portals。可以渲染子节点到不同的 DOM 子树中。欲了解更多详细信息,请参阅有关 portals 的文档

            4.字符串或数值类型。它们在 DOM 中会被渲染为文本节点

            5.布尔类型或 null。什么都不渲染。(主要用于支持返回 test && <Child /> 的模式,其中 test 为布尔类型。)

           注意如果 shouldComponentUpdate() 返回 false,则不会调用 render()

    二、constructor(props) :  如果不初始化 state 或不进行方法绑定,则不需要为 React 组件实现构造函数。  

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

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

                1.通过给 this.state 赋值对象来初始化内部 state

              2.为事件处理函数绑定实例

             在 constructor() 函数中不要调用 setState() 方法。如果你的组件需要使用内部 state,请直接在构造函数中为 this.state 赋值初始 state:

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

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

           你可以在 componentDidMount() 里直接调用 setState()。它将触发额外渲染,但此渲染会发生在浏览器更新屏幕之前。如此保证了即使在 render() 两次调用的情况下,用户也不会看到中间状态。请谨        慎使用该模式,因为它会导致性能问题。通常,你应该在 constructor() 中初始化 state。如果你的渲染依赖于 DOM 节点的大小或位置,比如实现 modals 和 tooltips 等情况下,你可以使用此方式处理

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

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

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

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

         见,但会影响组件性能。不要将 props “镜像”给 state,请考虑直接使用 props。 欲了解更多有关内容,请参阅为什么 props 复制给 state 会产生 bug 

         如果组件实现了 getSnapshotBeforeUpdate() 生命周期(不常用),则它的返回值将作为 componentDidUpdate() 的第三个参数 “snapshot” 参数传递。否则此参数将为 undefined。

        注意如果 shouldComponentUpdate() 返回值为 false,则不会调用 componentDidUpdate()

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

     注意:componentWillUnmount()中不应调用 setState(),因为该组件将永远不会重新渲染。组件实例卸载后,将永远不会再挂载它。

     

    六、不常用的生命周期方法  :

      shouldComponentUpdate(nextProps, nextState) :的返回值,判断 React 组件的输出是否受当前 state 或 props 更改的影响。默认行为是 state 每次发生变化组件都会重新渲染。大部分情况

                                    下,你应该遵循默认行为。

         static getDerivedStateFromProps(props, state):会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。它应返回一个对象来更新 state,如果返回 null 则不更新任何内

                                      容。

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

                                                              给 componentDidUpdate()。此用法并不常见,但它可能出现在 UI 处理中,如需要以特殊方式处理滚动位置的聊天线程等。应返回 snapshot 的值(或 null)。

     

         Error boundaries () : 是 React 组件,它会在其子组件树中的任何位置捕获 JavaScript 错误,并记录这些错误,展示降级 UI 而不是崩溃的组件树。Error boundaries 组件会捕获在渲染期间,

                                             生命周期方法以及其整个树的构造函数中发生的错误。如果 class 组件定义了生命周期方法 static getDerivedStateFromError() 或 componentDidCatch() 

                                             中的任何一个(或两者),它就成 为 了 Error boundaries。通过生命周期更新 state 可让组件捕获树中未处理的 JavaScript 错误并展示降级 UI。

                                             仅使用 Error boundaries 组件来从意外异常中恢复的情况;不要将它们用于 流程控制。欲了解更多详细信息,请参阅 React 16 中的错误处理                                    

                                             注意 :Error boundaries 仅捕获组件树中以下组件中的错误。但它本身的错误无法捕获。
       
     static getDerivedStateFromError():此生命周期会在后代组件抛出错误后被调用。 它将抛出的错误作为参数,并返回一个值以更新 state                                                     

                                            注意 :getDerivedStateFromError() 会在渲染阶段调用,因此不允许出现副作用。 如遇此类情况,请改用 componentDidCatch()

        componentDidCatch(error, info)此生命周期在后代组件抛出错误后被调用。 它接收两个参数:

        1.error —— 抛出的错误。

               2.info —— 带有 componentStack key 的对象,其中包含 有关组件引发错误的栈信息

       会在“提交”阶段被调用,因此允许执行副作用。 它应该用于记录错误之类的情况:

                       class 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; 
                  }
              }

          注意:如果发生错误,你可以通过调用 setState 使用 componentDidCatch() 渲染降级 UI,但在未来的版本中将不推荐这样做。 可以使用静态 getDerivedStateFromError() 来处理降级渲染。

  • 相关阅读:
    POJ2142:The Balance——题解
    POJ1061:青蛙的约会——题解
    接口测试结束后的小结
    接口测试结束后的小结
    如何进行需求测试/需求评审
    如何进行需求测试/需求评审
    测试人员掌握代码的重要性
    测试人员掌握代码的重要性
    测试人员掌握代码的重要性
    软件自动化测试开发-开班啦
  • 原文地址:https://www.cnblogs.com/whx123/p/12118102.html
Copyright © 2020-2023  润新知