涉及嵌套组件时,我正在努力理解componentDidMount()方法

时间:2019-04-06 02:17:05

标签: reactjs react-lifecycle-hooks

我试图了解反应生命周期挂钩,并遇到了componentDidMount()生命周期挂钩的问题。

假设您正在渲染组件列表。在呈现所有列表项之后,总是在最后触发每个列表项的componentDidMount()方法。为什么每个项目一开始都没有触发?

这是我的根App组件中的render()方法

  render() {
    return (
      <div className="App">
        <A>
          <A1 />
          <A2 />
        </A>
        <B>
          <B1 />
          <B2 />
        </B>
      </div>
    );
  }
}

单个组件A,A1,A2,B,B1,B2的结构看起来都一样,只是名称不同。

import React, { Component } from "react";

class A extends Component {
  constructor(props) {
    super(props);

    this.state = {};

    console.log(" [A.js] constructor()");
  }

  componentWillMount() {
    console.log(" [A.js] ComponentWillMount()");
  }

  componentDidMount() {
    console.log(" [A.js] ComponentDidMount()");
  }

  render() {
    console.log(" [A.js] render()");
    return <div>{this.props.children}</div>;
  }
}

export default A;

并且我已经在所有组件的每个方法中编写了控制台日志。下面是我的截图。 https://snag.gy/wyi5Ta.jpg

在屏幕截图中我们得到了

[App.js] constructor()
[App.js] componentWillMount()
[App.js] render()
 [A.js] constructor()
 [A.js] ComponentWillMount()
 [A.js] render()
  [A1.js] constructor()
  [A1.js] ComponentWillMount()
  [A1.js] render()
  [A2.js] constructor()
  [A2.js] ComponentWillMount()
  [A2.js] render()
 [B.js] constructor()
 [B.js] ComponentWillMount()
 [B.js] render()
  [B1.js] constructor()
  [B1.js] ComponentWillMount()
  [B1.js] render()
  [B2.js] constructor()
  [B2.js] ComponentWillMount()
  [B2.js] render()
  [A1.js] ComponentDidMount()
  [A2.js] ComponentDidMount()
 [A.js] ComponentDidMount()
  [B1.js] ComponentDidMount()
  [B2.js] ComponentDidMount()
 [B.js] ComponentDidMount()
[App.js] componentDidMount()

我在期待

[App.js] constructor()
[App.js] componentWillMount()
[App.js] render()
 [A.js] constructor()
 [A.js] ComponentWillMount()
 [A.js] render()
  [A1.js] constructor()
  [A1.js] ComponentWillMount() <---
  [A1.js] render()
  [A1.js] ComponentDidMount()
  [A2.js] constructor()
  [A2.js] ComponentWillMount() <---
  [A2.js] render()
  [A2.js] ComponentDidMount()
 [A.js] ComponentDidMount() <---
 [B.js] constructor()
 [B.js] ComponentWillMount()
 [B.js] render()
  [B1.js] constructor()
  [B1.js] ComponentWillMount()
  [B1.js] render()
  [B1.js] ComponentDidMount() <---
  [B2.js] constructor()
  [B2.js] ComponentWillMount()
  [B2.js] render()
  [B2.js] ComponentDidMount() <---
 [B.js] ComponentDidMount()
[App.js] componentDidMount()

我在希望componentDidMount()方法触发的位置放置了箭头。这是什么原因?

我找不到这个问题的确切答案。我还发现react遵循“深度优先搜索”遍历方法。我看了一些视频,但听不懂这个谜。有人可以解释一下吗?我现在已经花了几个小时来解决这个问题。谢谢。

1 个答案:

答案 0 :(得分:0)

React组件的构造函数在挂载之前被调用。

https://reactjs.org/docs/react-component.html#constructor

UNSAFE_componentWillMount()在挂载发生之前被调用。在render()之前调用它,因此,在此方法中同步调用setState()不会触发额外的渲染。

https://reactjs.org/docs/react-component.html#unsafe_componentwillmount

componentDidMount()在安装组件(插入树中)后立即被调用。

https://reactjs.org/docs/react-component.html#componentdidmount

根据文档,一切都会按预期进行。在将[B.js] render()插入树之前,只需调用[A1.js]。删除[B.js]和孩子,它仍然可以正常工作。

重要的是,父componentDidMount在挂载子项之后被调用,否则将无法执行计算父节点的高度,因为触发componentDidMount时父节点的高度仍然为空。

https://github.com/facebook/react/issues/14753

https://blog.bitsrc.io/understanding-asynchronous-javascript-the-event-loop-74cd408419ff