javascript 为什么不应该使用 componentWillMount?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/46043832/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why componentWillMount should not be used?
提问by Lokesh Agrawal
Firing server call to fetch data in componentWillMount life cycle method a bad practice?
触发服务器调用以在 componentWillMount 生命周期方法中获取数据是一种不好的做法?
And why it is better to use componentDidMount.
以及为什么最好使用 componentDidMount。
采纳答案by Lyubomir
UPDATE:componentWillMount will soon be deprecated.
更新:componentWillMount 将很快被弃用。
To cite @Dan Abramov
In future versions of React we expect that componentWillMount will fire more than oncein some cases, so you should use componentDidMount for network requests.
在React 的未来版本中,我们预计 componentWillMount在某些情况下会触发不止一次,所以你应该使用 componentDidMount 来处理网络请求。
Read more here.
在这里阅读更多。
回答by Sagiv b.g
UPDATE - may / 2018
There is a new feature for react in a working progress called async rendering.
As of react v16.3.2these methods are not "safe" to use:
更新 - 2018 年 5 月
有一项新功能可用于在称为异步渲染的工作进度中做出反应。
作为反应,v16.3.2这些方法使用起来并不“安全”:
- componentWillMount
- componentWillReceiveProps
- componentWillUpdate
- 组件将挂载
- 组件将接收道具
- 组件将更新
you can read more about it in the docs.
你可以在文档中阅读更多关于它的信息。
As a general rule don't usecomponentWillMountat all (if you use the es6 classsyntax). use the constructormethod instead.
This life-cycle method is good for a sync state initialization.componentDidMountin the other hand is good for async state manipulation.
作为一般规则,根本不要使用componentWillMount(如果您使用 es6class语法)。改用该constructor方法。
这种生命周期方法适用于同步状态初始化。componentDidMount另一方面有利于异步状态操作。
Why?
Well, when you do an async request in the constructor/ componentWillMountyou do it before rendergets called, by the time the async operation has finished the rendermethod most probably already finished and no point to set the "initial state" at this stage is it?.
I'm not sure this is your case here, but most of the cases that developers wants to initiate state asynchronously in componentWillMountis to avoid a second rendercall. but you can't avoid it can you, like mentioned above, renderwill fire anyway before the async operation will finish.
So, the best time to call an async operation is after a renderhas called and the component mounted (you could mount nullor an empty <div/>) and then fetch your data, set the state and make it re-render respectively.
为什么?
好吧,当您在constructor/ 中执行异步请求时,componentWillMount您会在render调用之前执行此操作,当异步操作完成时,该render方法很可能已经完成并且在此阶段设置“初始状态”没有意义,是吗?
我不确定这是您的情况,但开发人员希望异步启动状态的大多数情况componentWillMount是为了避免第二次render调用。但是你无法避免它,就像上面提到的那样,render在异步操作完成之前无论如何都会触发。
因此,调用异步操作的最佳时间是在render已调用并安装组件之后(您可以安装null或空<div/>) 然后获取您的数据,设置状态并使其分别重新渲染。
回答by mradziwon
componentDidMountis the best place to put calls to fetch data, for two reasons:
componentDidMount是调用获取数据的最佳位置,原因有二:
Using
componentDidMountmakes it clear that data won't be loaded until after the initial render. You need to setup initial state properly, so you don't getundefinedstate that causes errors.If you need to render your app on the server,
componentWillMountwill be called twice(on the server and again on the client), which is probably not what you want. Putting the data loading code incomponentDidMountwill ensure that data is only fetched from the client. Generally, you should not add side effects tocomponentWillMount.
Using
componentDidMount清楚地表明在初始渲染之后才会加载数据。您需要正确设置初始状态,以免获得undefined导致错误的状态。如果您需要在服务器上呈现您的应用程序,
componentWillMount将被调用两次(在服务器上和在客户端上再次调用),这可能不是您想要的。放入数据加载代码componentDidMount将确保仅从客户端获取数据。通常,您不应向componentWillMount.
回答by jonahe
The way I understand it, one of the biggest reasons has to do with setting up the right expectations for the developersreading the code.
根据我的理解,最大的原因之一与为阅读代码的开发人员设置正确的期望有关。
If we use componentWillMountit's tempting to think that the fetch have time to happen, then the component "did" mount, and thenthe first render will happen. But that it not the case. If we do an async call (like an API call with Promises), the component will actually run renderbefore the fetch can return and set the component state (or change the Redux state, or what ever).
如果我们使用componentWillMount它很容易认为 fetch 有时间发生,然后组件“确实”挂载,然后第一次渲染将发生。但事实并非如此。如果我们执行异步调用(例如使用 Promise 的 API 调用),组件将render在获取返回并设置组件状态(或更改 Redux 状态,或其他任何事情)之前实际运行。
If we instead use componentDidMount, then it's clear that the component will render at least once before you get back any data (because the component already didmount). So, by extension, it's also clear that we have to handle the initial state in a way so that the component doesn't break on the first ("empty") render.
如果我们转而使用componentDidMount,那么很明显,该组件将呈现至少一次,你回来任何数据之前(因为部分已经没安装)。因此,通过扩展,很明显我们必须以某种方式处理初始状态,以便组件不会在第一次(“空”)渲染时中断。
回答by Devinder Suthwal
Component Mounting life cycle is
组件安装生命周期是
- constructor()
- componentWillMount() /UNSAFE_componentWillMount()(react 16)
- render()
- componentDidMount()
- 构造函数()
- componentWillMount() /UNSAFE_componentWillMount()(react 16)
- 使成为()
- 组件DidMount()
Constructorand componentWillMountboth call before render() call which is responsible for page rendering.
Constructor和componentWillMount都在负责页面渲染的 render() 调用之前调用。
Here State initialized is done in Constructor and api are called in componentDidMount because of async calls.
由于异步调用,这里的 State 初始化是在 Constructor 中完成的,而 api 在 componentDidMount 中被调用。
ComponentWillMount was good to initialized state before ES6when constructor was not there. But now ComponentWillMount is good for nothing and react team is thinking it after react 17.
当构造函数不存在时,ComponentWillMount 可以很好地初始化 ES6 之前的状态。但是现在 ComponentWillMount 一无是处,React 团队在 React 17 之后开始考虑它。
In additionto above, react have moved to react fiber architecture, to avoid unnecessary re-rendering and improve performance, react has decided to move away from componentWillMount, componentWillReciveProps and componentWillUpdate methods.
除了上述之外,react 已经转移到 react纤维架构,为了避免不必要的重新渲染和提高性能,react 决定远离 componentWillMount、componentWillReciveProps 和 componentWillUpdate 方法。

