首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >componentDidUpdate是否会在所有子项都更新后运行?

componentDidUpdate是否会在所有子项都更新后运行?
EN

Stack Overflow用户
提问于 2017-03-21 07:50:17
回答 3查看 16.4K关注 0票数 19

我想知道React组件的生命周期方法componentDidUpdate是在所有子组件的render方法完成之后执行的,还是在该组件的render方法被调用之后执行的。

由于协调器递归地调用render方法来更新视图,因此我预感到componentDidUpdate是在重新呈现组件的所有子组件之后执行的,但是documentation中没有足够的信息。componentDidUpdate的确切调用时间是什么时候?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-03-21 08:13:45

在组件的render方法执行完毕后,调用componentDidUpdate方法。这意味着它将在所有子对象的render方法完成后调用。这在您链接的文档中是隐含的:

当组件更新后,

利用这一机会在DOM 上进行操作。

该组件仅在渲染后更新,因此文档暗示它是在所有子组件完成重新渲染(尽管是a bit unclear)之后调用的,因此父组件也是如此。只有当DOM完成更新时,您才能真正对其进行操作。

例如,假设我们有两个组件,ABB呈现一个A组件。BcomponentDidUpdate将仅在Brender完成后调用。Brender将在Arender被成功调用后结束,因为由于是父对象的一部分,子对象首先被呈现。这意味着对您问题的回答是:componentDidUpdate在所有子对象的<代码>d21完成后执行。

票数 26
EN

Stack Overflow用户

发布于 2017-03-21 08:03:02

不确定是否有更深入的文档,但它确实足够简单,可以自己测试。

代码语言:javascript
复制
class Nested extends React.Component {
  constructor(props){
    super(props);
    this.state = {foo: undefined};
  }
  render() {
    console.log("Rendered " + this.props.name);
    return <div><button onClick={() => {this.setState({foo: Date.now()})}}>Update {this.props.name}</button>{this.props.children ? React.cloneElement(React.Children.only(this.props.children), {foo: this.state.foo}) : undefined}</div>
  }
  componentDidUpdate() {
    console.log("Updated " + this.props.name);
  }
}

ReactDOM.render(<Nested name="outer"><Nested name="inner"></Nested></Nested>, document.getElementById("app"));

http://jsbin.com/yiyuhegayo/edit?js,console,output

更新外部组件会导致最内层的componentDidUpdate首先运行,然后是最外层的。更新内部组件只会导致该组件更新。

有趣的是,render函数的情况正好相反。外部组件首先呈现,然后是内部组件。

票数 7
EN

Stack Overflow用户

发布于 2020-07-13 18:22:46

正如@Andrew Li正确指出的那样,componentDidUpdate是在所有子级都被渲染之后执行的。虽然这仍然成立,但从那时起,React的光纤协调算法( 16.0版以上)可能已经改变了之前的假设。

简而言之,React将工作分为两个阶段,render (先执行)阶段和commit (在render之后执行)阶段。componentDidUpdate属于commit阶段,是此阶段中调用的最后一个生命周期方法(在getSnapshotBeforeUpdatecomponentWillUnmountcomponentDidMount之后),因此将始终在渲染节点及其子节点之后发生。

render阶段以“深度优先”遍历光纤树,如下图所示(取自强烈推荐的Inside Fiber: in-depth overview of the new reconciliation algorithm in React)。

(子节点是水平显示的,因此c1b2的子节点,b3b2的同级节点,而b1没有任何子节点。)

此外,组件可能会重新呈现(例如,在状态更改后,即席,连接的props...etc),这不会在父级上触发componentDidUpdate。我认为这种情况一直存在,甚至在v16.0之前就是如此。

如上所述,我认为对子组件的呈现做出假设是不寻常的(而且可能是不安全的),并且会在这些组件之间创建不必要的耦合,并建议每个组件都足够模块化,以便不依赖于其父组件的componentDidUpdate或子组件的render()。如果需要通知父对象子对象(Ren)已完成渲染,可以将函数作为道具传递,然后在componentDidUpdatecomponentDidMount (或useEffect)中调用该函数。

沙盒:https://codesandbox.io/s/react-rendering-tr59s

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42916045

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档