ReactJS中的componentWillMount和componentDidMount有什么区别?


91

我在(React.Component)上查看了Facebook的文档,其中提到了如何componentWillMount在客户端/服务器componentDidMount上调用而仅在客户端上调用。这是什么componentWillMount做的服务器?

Answers:


71

componentWillMount本质上是构造函数。您可以设置不影响渲染的实例属性,同步从存储中提取数据并使用setState 设置实例属性,以及设置组件时需要运行的其他简单的无副作用代码。

它很少需要,ES6类根本不需要。


63

constructor方法是不一样的componentWillMount

根据Redux的作者所说,从构造函数中分派动作是有风险的,因为它可能导致渲染时改变状态。

但是,从调度componentWillMount就可以了。

来自github问题

当一个组件的构造函数中的dispatch()导致另一个组件内部的setState()时,就会发生这种情况。React会跟踪此类警告的“当前所有者”,并认为当技术上构造函数在应用程序其他部分内引起setState()时,我们正在构造函数内调用setState()。我不认为我们应该处理这个问题,这只是React尽力而为。正如您正确指出的那样,该解决方案是改为在componentWillMount()内部进行dispatch()。


绝对不是在所有情况下都很好,这取决于in中的内容componentXxxMount,例如Ajax in willMount可能会引起问题。
戴夫牛顿

2
@DaveNewton我并不是在所有情况下都说得很好。我只是举了一个例子,其中有一个差异可以证明答案“ componentWillMount本质上是构造函数”是错误的。感谢澄清出来
丽然布里默

@LiranBrimer由于不赞成componentWillMount,该答案变得不准确,并且将分别在0.16和0.17中停止运行,特别是关于“但是,从componentWillMount派发就很好了”。声明
Brian Webster

37

要补充FakeRainBrigand所说的,componentWillMount在服务器和客户端上渲染React时会被调用,但componentDidMount只会在客户端上被调用。


10
componentWillMount将在服务器和客户端上调用。见:facebook.github.io/react/docs/...
大卫·

1
@DaveNewton怎么样?它并没有说componentWillMount不会
拜访

7
@AyushShanker IMO提供非误导性信息非常重要。由于不明确,存在误解的余地:文档是明确的。您是正确的,它也不明显矛盾。
戴夫牛顿

31

componentWillMountrender组件的INITIAL之前完成,用于评估道具并基于它们执行任何额外的逻辑(通常还用于更新状态),因此可以在服务器上执行以获取第一个服务器端呈现的标记。

componentDidMountrender在DOM更新后的初始操作之后执行的(但至关重要的是,在此DOM更新绘制到浏览器之前,允许您与DOM本身进行各种高级交互)。当然,这只能在浏览器本身中发生,因此不会作为SSR的一部分发生,因为服务器只能生成标记,而不能生成DOM本身,这是在使用SSR发送到浏览器后完成的。

您说的与DOM的高级交互?Whaaaat ?? ...是的-由于DOM已更新(但是用户尚未在浏览器中看到更新),因此可以通过使用拦截实际绘制到屏幕上window.requestAnimationFrame,然后执行诸如测量实际可以输出的DOM元素,您可以对其进行进一步的状态更改,例如,将具有未知可变长度内容的元素的高度动画化(因为您现在可以测量内容并为动画分配高度)非常有用,或避免在某些状态更改期间出现内容闪烁的情况。

但是要非常小心componentDid...,以免发生任何状态变化,否则可能会导致无限循环,因为状态变化还会导致重新渲染,因此会不断渲染componentDid...


1
我不认为将setStatecomponentDidMount会导致无限循环。
玛迪

否则会导致无限循环,因为状态更改还将导致重新渲染,并因此导致另一个componentDidMount。并且不停地重复 ”,这是完全不正确的。状态更改将导致重新渲染,但不会componentDidMount一次又一次地调用。挂载组件时,componentDidMount仅被调用一次。
hussain.codes


2

componentWillMount https://daveceddia.com/where-fetch-data-componentwillmount-vs-componentdidmount/

但是,这有一个“陷阱”:在渲染发生之前,异步调用将不会获取数据。这意味着该组件将使用空数据至少渲染一次。

无法“暂停”渲染以等待数据到达。您不能以某种方式从componentWillMount返回诺言或在setTimeout中争执。

https://developmentarc.gitbooks.io/react-indepth/content/life_cycle/birth/premounting_with_componentwillmount.html

我们的组件将无权访问本机UI(DOM等)。我们也将无法访问子引用,因为它们尚未创建。componentWillMount()是我们处理配置,更新状态以及总体上准备第一个渲染的机会。这意味着我们可以根据道具值开始执行计算或处理。


1

componentWillMount()的用例

例如,如果要在组件状态中保留创建组件的日期,则可以在此方法中进行设置。请记住,使用此方法设置状态不会重新渲染DOM。记住这一点很重要,因为在大多数情况下,只要我们更改组件的状态,就会触发重新渲染。

componentWillMount() {
  this.setState({ todayDate: new Date(Date.now())});
}

componentDidMount()的用例

例如,如果您正在构建一个新闻应用程序,该应用程序将获取当前新闻中的数据并将其显示给用户,并且您可能希望每小时更新一次此数据,而无需用户刷新页面。

componentDidMount() {
  this.interval = setInterval(this.fetchNews, 3600000);
}

0

ComponentDidMount()方法仅更改类组件中的当前页面,但ComponentWillMount()更改由setStates()

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.