首頁 > webfront > ECMAS > react > > 正文

react異步數據如ajax請求應該放在哪個生命周期?

發布人:zhoulujun    點擊:

react請求接口數據是在componentDidMount 還是componentWillMount周期好?React數據獲取為什么一定要在componentDidMount里面調用?

對于同步的狀態改變,是可以放在componentWillMount,對于異步的,最好好放在componentDidMount。但如果此時有若干細節需要處理,比如你的組件需要渲染子組件,而且子組件取決于父組件的某個屬性,那么在子組件的componentDidMount中進行處理會有問題:因為此時父組件中對應的屬性可能還沒有完整獲取,因此就讓其在子組件的componentDidUpdate中處理。

至于為什么,先看看react的生命周期

constructor() 》componentWillMount() 》render() 》componentDidMount()

上面這些方法的調用是有次序的,由上而下,也就是當說如果你要獲取外部數據并加載到組件上,只能在組件"已經"掛載到真實的網頁上才能作這事情,其它情況你是加載不到組件的。


componentDidMount方法中的代碼,是在組件已經完全掛載到網頁上才會調用被執行,所以可以保證數據的加載。此外,在這方法中調用setState方法,會觸發重渲染。所以,官方設計這個方法就是用來加載外部數據用的,或處理其他的副作用代碼。


constructor被調用是在組件準備要掛載的最一開始,所以此時組件尚未掛載到網頁上。


componentWillMount方法的調用在constructor之后,在render之前,在這方法里的代碼調用setState方法不會觸發重渲染,所以它一般不會用來作加載數據之用,它也很少被使用到。


一般的從后臺(服務器)獲取的數據,都會與組件上要用的數據加載有關,所以都在componentDidMount方法里面作。雖然與組件上的數據無關的加載,也可以在constructor里作,但constructor是作組件state初紿化工作,并不是設計來作加載數據這工作的,所以所有有副作用的代碼都會集中在componentDidMount方法里。


constructor()中獲取數據的話,如果時間太長,或者出錯,組件就渲染不出來,你整個頁面都沒法渲染了。

componentDidMount()中能保證你的組件已經正確渲染。

總結下:

1.跟服務器端渲染(同構)有關系,如果在componentWillMount里面獲取數據,fetch data會執行兩次,一次在服務器端一次在客戶端。在componentDidMount中可以解決這個問題。

2.在componentWillMount中fetch data,數據一定在render后才能到達,如果你忘記了設置初始狀態,用戶體驗不好。

3.react16.0以后,componentWillMount可能會被執行多次。


參考:

segmentfault: React數據獲取為什么一定要在componentDidMount里面調用?

React 異步渲染組件優化