gpt4 book ai didi

javascript - React componentDidMount 计时

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:29:41 25 4
gpt4 key购买 nike

componentDidMount 生命周期方法是否独立于兄弟组件?从下面的示例来看,它似乎仅在所有同级组件都已安装后才被调用。

假设我们有一个顶级组件,它呈现 2 个子组件,第一个具有简单的 render(),另一个具有相对较慢的 render()

重现样本:https://codesandbox.io/s/j43klml9py?expanddevtools=1

长话短说:


class SlowComponent extends Component {
componentDidMount() {
// perf mark
}

render() {
// Simulate slow render
// Takes 50ms
return <h3>Slow component</h3>;
}
}

class FastComponent extends Component {
componentDidMount() {
// perf mark
}

render() {
return <h3>Fast component</h3>;
}
}

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

// perf mark start
}

componentDidMount() {
// perf mark
// measure all marks and print
}

render() {
return (
<div>
<FastComponent />
<SlowComponent />
</div>
);
}
}

ReactDOM.render(<App />, document.getElementById('root'));

我希望 componentDidMount 的时间是这样的:

  1. FastComponent 10 毫秒
  2. SlowComponent 50 毫秒
  3. 应用 52 毫秒

但实际上我得到的是同时触发快速和慢速组件 componentDidMount 回调,即

  1. FastComponent 50 毫秒
  2. SlowComponent 51 毫秒
  3. 应用 52 毫秒

当前示例和重现代码使用挂载回调,但同样适用于 componentDidUpdate

完整来源:

import ReactDOM from "react-dom";
import React, { Component } from "react";

class SlowComponent extends Component {
componentDidMount() {
performance.mark("slow-mounted");
}

render() {
// Simulate slow render
for (var i = 0; i < 10000; i++) {
for (var j = 0; j < 100; j++) {
const b = JSON.parse(
JSON.stringify({
test: "test" + i,
test1: i * i * i
})
);
}
}
return <h3>Slow component</h3>;
}
}

class FastComponent extends Component {
componentDidMount() {
performance.mark("fast-mounted");
}

render() {
return <h3>Fast component</h3>;
}
}

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

performance.mark("init");
}

componentDidMount() {
performance.mark("app-mounted");

performance.measure("slow", "init", "slow-mounted");
performance.measure("fast", "init", "fast-mounted");
performance.measure("app", "init", "app-mounted");

console.clear();

console.log(
"slow",
Math.round(performance.getEntriesByName("slow")[0].duration)
);
console.log(
"fast",
Math.round(performance.getEntriesByName("fast")[0].duration)
);
console.log(
"app",
Math.round(performance.getEntriesByName("app")[0].duration)
);

performance.clearMarks();
performance.clearMeasures();
}

render() {
return (
<div>
<h1>Demo</h1>
<FastComponent />
<SlowComponent />
</div>
);
}
}

ReactDOM.render(<App />, document.getElementById("root"));

最佳答案

我假设您使用的是最新的 React 版本 (16.5.0)。

假设有两个组件,一个慢,一个快,包裹在父组件中,执行流程如下:

  1. 父组件调用它的 UNSAFE_componentWillMount 方法
  2. 按照在其渲染方法中定义的顺序迭代所有子级并调用它们的 UNSAFE_componentWillMount 方法
  3. 迭代所有的 child 并调用他们的render方法(这里你的慢组件昂贵的渲染方法将启动)
  4. 迭代所有的 child 并调用他们的componentDidMount方法
  5. 父组件调用它的componentDidMount方法

整个过程是同步进行的。

回到您的示例,这就是为什么您看到两个组件的时间几乎相同,因为一旦所有组件的工作完成,就会调用所有组件生命周期方法。

一般来说,React 在概念上由两个阶段组成,“渲染”阶段和“提交”阶段。“提交”阶段是 React 应用任何更改的时候,在您的示例中,生命周期方法 componentDidMount 在此阶段被调用。

您可以通过调试 React 并查看以下堆栈跟踪来遵循此流程:

componentDidMount
commitLifeCycles
commitAllLifeCycles
callCallback
invokeGuardedCallbackDev
invokeGuardedCallback
commitRoot

关于javascript - React componentDidMount 计时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52185372/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com