为什么React文档建议在componentDidMount中而不是componentWillMount中进行AJAX?


102

标题说明了一切。我知道为什么componentDidMount它适用于需要DOM访问的任何内容,但是AJAX请求不一定或通常都需要这样做。

是什么赋予了?


@FurkanO我认为他的意思是访问由组件呈现的DOM元素。他是完全正确的,因为如果您尝试访问其中的元素,componentWillMount则由于未安装该组件而将失败。
ZekeDroid '16

@AlanH。删除了我的问题,您当然可以在componentDidMount上访问dom。这是一条规则,对此没有任何解释。谢谢。
FurkanO 2016年

我认为,为什么我们要在componentDidMount之后调用Ajax函数,是我们必须首先确保Element在开始时平滑呈现。之后,我们可以进行ajax调用。如果我们先调用ajax并发生错误,它将导致渲染问题
Faris Rayhan

Answers:


62

componentDidMount用于副作用。添加事件侦听器,AJAX,更改DOM等。

componentWillMount很少有用;特别是如果您关心服务器端渲染(添加事件侦听器会导致错误和泄漏,以及许多其他可能出错的东西)。

讨论componentWillMount从类组件中删除组件是因为它的作用与构造函数相同。它将保留在createClass组件上。


1
添加事件侦听器会导致错误,并始终在服务器上或仅在服务器中泄漏componentWillMount?我看不出这种区别。
艾伦H.14年

18
@Alan-如果您同时在客户端和服务器端都使用React,则会发现其中的任何内容componentWillMount都将在服务器端渲染器上执行。如果您正在使用Wheras,则componentDidMount只能在客户端执行。结果,将事物放入componentWillMount执行外部交互或绑定到事件等中的想法并不是一个好主意。如果您没有计划在服务器端渲染组件,那么考虑到潜在的代码可移植性,这仍然不是一个好主意。这是所有不好的主要原因,这在@daniula的答案中进行了解释。
Mike Driver

3
componentWillMount在服务器上运行,但没有运行componentWillUnmount(在其中删除侦听器)。这将导致您添加侦听器,并且从不对其进行清理。
旅团

React核心团队的成员正在考虑从将来的版本中删除componentWillMount。
cchamberlain

1
@AnkitSinghaniya会破坏服务器渲染和浅层单元测试。
旅团

36

一开始我也遇到了同样的问题。我决定尝试提出请求,componentWillMount但最终遇到各种小问题。

当ajax调用完成新数据时,我正在触发渲染。在某个时刻,组件渲染比从服务器获得响应要花费更多的时间,并且此时ajax回调正在触发未安装组件的渲染。这是一种边缘情况,但可能还有更多,因此坚持下去是更安全的componentDidMount


好的谢谢。认为可能是这样,但是您是对的,令人惊讶的是,ajax请求可以在呈现之前完成。
艾伦H.14年

1
@daniula您确定吗?渲染之前AJAX请求如何完成?
Leon Grapenthin

4
这是浏览器异步的世界。您永远不要以为一个功能总是比其他功能更快。正如我已经提到的那样,这是一个极端的情况,可能意味着您应该优化渲染过程,但是此时使用适当的生命周期方法将使您的生活更加轻松。
daniula

1
@SooChengKoh ES6类构造函数等效于componentWillMount,因此您仍应继续使用其componentDidMountajax调用。
daniula

1
@SooChengKoh-绝对不应在构造函数中执行任何操作,否则将导致必须设置的状态,这将导致客户端和服务器上的争用条件。您永远不要调用setState组件构造函数,也无法确定AJAX调用何时完成。twitter.com/dan_abramov/status/576453138598723585
cchamberlain

3

根据文档设置,该状态componentWillMount不会触发重新渲染。如果AJAX调用没有阻塞,并且Promise成功返回一个更新组件状态的,则一旦呈现了组件,响应就有可能到达。如componentWillMount不会触发重新渲染,因此您将不会具有预期的行为,即使用请求的数据渲染的组件。

如果您使用任何助焊剂库,并且所请求的数据最终存储在该组件已连接到(或从已连接的组件继承)的商店中,那么这将不是问题,因为该数据的接收很可能会更改道具最终。


1
componentWillMount不会仅仅因为在第一个渲染之前定义了新状态而触发重新渲染。但是,如果setState在AJAX回调中调用,则在第一个渲染之后肯定会调用它,并且它将触发重新渲染。
webdif
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.