1

我试图了解反应生命周期钩子,并遇到了 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 遵循“深度优先搜索”遍历方法。我看了一些视频,但无法理解这个奥秘。有人可以解释一下吗?我一直在努力解决这个问题。谢谢。

4

1 回答 1

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

于 2020-12-10T13:23:52.110 回答