我试图了解反应生命周期挂钩,并遇到了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遵循“深度优先搜索”遍历方法。我看了一些视频,但听不懂这个谜。有人可以解释一下吗?我现在已经花了几个小时来解决这个问题。谢谢。
答案 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