为什么 addChangeListener 应该在 componentDidMount 而不是 componentWillMount?

IT技术 javascript reactjs reactjs-flux flux
2021-04-28 16:28:37

我看到这条线是对这里另一个问题的回答:

“componentWillMount 应该是 componentDidMount,否则你会在 node 中泄漏事件发射器。”

我真的不明白。有人可以更详细地解释一下吗?

更多信息:

使用 Flux 构建 React 应用程序,作为初始渲染的一部分,子组件计算一些数据。理想情况下,在计算完这些数据后,我想调用一个操作,用该新数据的一部分更新商店的状态。

通常,更新商店的状态会发出导致重新渲染的更改事件。但是,因为直到 componentDidMount(而不是在 componentWillMount 中)才会添加更改侦听器,所以我的顶级组件无法侦听初始渲染期间发生的更改并启动重新渲染。

如果我将 addChangeListener 移动到 componentWillMount 似乎可以解决这个问题,但上面的引用表明这是一个坏主意?

2个回答

我认为应该设置侦听器的普遍智慧是componentDidMount因为它可以防止同构应用程序中出现问题。我认为,在非同构应用程序在任何设置下听众的病例98%componentWillMountcomponentDidMount将同样的方式工作,但它在概念上的错误,在情况下(如在原来的问题给出的例子)的2%,它会做错的东西。

React 源代码中有 git 问题讨论和评论表明最好componentWillMount根本不在服务器上调用,但如果不是,则在比较服务器预渲染和客户端的校验和测试中会产生问题初始渲染。componentWillMount服务器上意味着在这种情况下它不会作为组件生命周期的一部分执行,但这被用作在任何情况下都不将其视为生命周期一部分的借口。

事实上,componentWillMount如果您不是在创建同构应用程序,那么这正是注册侦听器的正确位置。如果您正在创建同构应用程序,那么您必须做出一些妥协,因为在这种情况下校验和/生命周期问题并不理想(也许只是测试服务器环境,然后不注册侦听器?)。

在非同构应用程序中,componentWillMount在某些情况下添加侦听器可以节省不必要的重新渲染,并将按文档顺序注册它们。文档顺序的优点是,如果您有办法在重新渲染组件时刷新挂起的事件(例如,takeRecords在 a 上MutationObserver),那么您可以确保文档自上而下而不是自下而上重新渲染,从而转换渲染复杂性从多项式到线性。

此外,在初始渲染和注册侦听器之间没有危险期,其中 Store 可以更改而不触发渲染,导致视图与 Store 不同步(原始问题中给出的示例问题)。如果侦听器已注册,componentDidMount您要么需要确保 StorecomponentDidMount在子代调用中未更改,要么在注册侦听器后强制重新渲染/重新同步,如果完成,componentDidMount则以相反的文档顺序完成可能是多项式复杂度(取决于 ReactsetStates的聚合方式/是否聚合)。

如果没有更多上下文,很难理解该引用的含义。我可以告诉你的是,这两种方法之间存在巨大差异。

一方面,componentWillMount在组件实际添加到 DOM 之前调用。这是您必须在浏览器呈现组件之前更新组件状态并使其呈现的最后机会。

另一方面,componentDidMount一旦组件被附加到 DOM(真正的)就会被调用。

您需要什么实际上取决于您的用例。一般来说,componentDidMount用于与其他库(如 jQuery)集成,它提供了一种修改组件呈现的 HTML 的方法。

我建议您阅读以下链接: