constructor(經常使用) -> getInitialState(v16.0已廢棄) -> getDefaultProps(v16.0已廢棄) -> componentWillMount(v17.0中將被棄用) -> getDerivedStateFromProps(v16.3新增,並在v16.4中升級優化了一下) -> render(必需要) -> componentDidMount(經常使用)html
componentWillReceiveProps(v17.0中將被棄用) -> getDerivedStateFromProps -> shouldComponentUpdate -> componentWillUpdate(v17.0中將被棄用) -> render -> getSnapshotBeforeUpdate -> componentDidUpdatevue
componentWillUnmountreact
getDerivedStateFromError(v16.6新增) -> componentDidCatch(將來將被廢棄)ajax
ES6中每一個類的構造函數,並非每一個組件都須要定義本身的構造函數。好比無狀態組件。
做用:瀏覽器
state = { count: 0 } // 這是由於在ES6的繼承中,其實無論子類寫不寫constructor,在new實例的過程都會給補上constructor class ColorPoint extends Point { } // 等同於 class ColorPoint extends Point { constructor(...args) { super(...args); } }
返回值會用來初始化組件的this.state性能優化
返回值能夠做爲props的初始值網絡
能夠作:antd
- 直接使用setState改變組件狀態,render會打印一次改變後的值(可是你這樣作沒什麼意義,還不如直接在constructor的時候設好初始值)
- 發送Ajax請求(服務端渲染的時候)
不要作:dom
- 發送ajax請求(緣由以下)
- 執行DOM操做(這個階段DOM還沒渲染出來)
最終建議:異步
不要用這個生命週期
在沒被棄用的時候也幾乎不用,這時候沒有任何渲染出來的結果,即便調用this.setState修改狀態也不會引起從新繪製。全部在這裏能夠作的事,均可以提早到 constructor中去作。有些人可能用過vue, 在vue中也常常在created中去請求接口,好比可能初始值是0,而後在created中請求接口,簡單的理解成想頁面在展現的時候就直接顯示接口請求返回後的數據1了,而不是咱們看到頁面的時候先看到0,而後忽然變成1了。我的理解vue的created和react的componentWillMount應該也是相差不了太多的,若是是在componentWillMount的時候你的數據還不是1的話,你這時候請求數據,實際上是另外開了一個線程去執行異步操做了,render函數並不會等你異步請求結果返回1纔去執行render。網絡差的話,你先看到0再看到忽然變成1也是很正常的事。在這裏請求和在componentDidMount中請求並不會有太大的差異。同理,其實vue中特地區分該在created中仍是mounted中請求接口也是不必的,還不如統一到mounted/componentDidMount中去請求接口,由於咱們有些方法仍是要等真實dom存在後纔去執行的。
第一次在裝載階段(當前組件實例化)會被觸發比較好理解,可是組件更新階段,究竟組件更新階段的什麼操做會觸發這個函數?
假如我在父組件改變了props 會觸發這個函數嗎?答案是會。
假如我在當前組件 this.setState 會觸發這個函數嗎?在v16.3中不會,可是在v16.4以上就會了。截至2019-03-17,在 https://react.docschina.org/docs/react-component.html#static-getderivedstatefromprops 上看到的翻譯仍是錯的。不信能夠本身試試?
假如我在父組件只是執行了 forceUpdate 強行引起一次從新繪製,那當前組件(子組件)的getDerivedStateFromProps又會被觸發嗎?
同樣,在v16.3中不會,可是在v16.4以上就會了。
它返回一個對象來更新狀態,若是返回的是null就表示不更新任何內容
這個方法react官方都意識到不少人對如何使用它存在許多誤解(https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html),
目前不少人的博客其實寫得也有點問題的。
返回一個JSX表示的對象,而後由React庫來根據返回對象決定如何渲染。並非返回的真實DOM,其餘的生命週期均可以省,可是這個必需要
能夠作:
- 發送ajax請求
不要作:
- 直接使用this.setState更新狀態,這樣會二次渲染(不過常常會有發送請求後,在回調函數裏setState,這也是不可避免的)
僅在瀏覽器端執行,此時已經有了真實的dom節點,在這個階段經常使用於處理接口請求,或者一些DOM操做。由於有些組件的啓動動做是依賴DOM的,例如動畫等。
須要注意的是:能夠在這裏發送異步請求,在回調函數裏調用setState設置state。可是儘可能不要在這裏直接調用setState()設置狀態。由於會觸發一次額外的從新渲染,可能形成性能問題。
能夠作:
- 根據props的更新同步組件狀態。
不要作:
- 發送ajax請求
- 尤爲是不要在這裏setState
當前組件setState()不會調用;
父組件props改變會調用;
父組件經過forceUpdate從新執行render,也會調用當前組件的componentWillReceiveProps;
只要父組件的render函數被調用,那麼當前組件(子組件)都會觸發這個函數,無論父組件的props發不發生變化。例如父組件執行了 forceUpdate 強行引起一次從新繪製。當前組件的componentWillReceiveProps就會被觸發。而在當前組件this.setState是不會觸發這個函數的。由於componentWillReceiveProps適合根據新的props值(也就是參數nextProps)來計算出是否是要更新內部狀態state。更新組件內部狀態的方法就是this.setState。若是this.setState的調用致使componentWillReceiveProps再依次被調用,那就是一個死循環了。
componentWillReceiveProps(nextProps) { if (this.props.oneProp !== nextProps.oneProp) { // 不少人會在這裏同時寫setState 而且 發送異步請求,其實這是不合理的 // 應該只在這裏根據props的改變去執行 setState來同步props到組件的狀態中, 不應在這裏發送異步請求 } } // 現現在更好的方式是使用getDerivedStateFromProps 去改變state 和 componentDidUpdate 去異步請求 來代替上面的方案
當前組件setState()會調用;
父組件props改變會調用;
父組件經過forceUpdate從新執行render,不會調用當前組件的shouldComponentUpdate;
這個方法主要是爲了性能優化而設計的,考慮使用內置的PureComponent,而不是本身在這個函數裏寫比較,更不建議在這個組件裏使用JSON.stringify去深度檢查,效率很是低。
這裏返回一個布爾值,默認都返回的true, 若是返回false,那這個生命週期後面的更新階段的生命週期都不會執行了。
它能夠作的,不要作的同componentWillMount同樣
當前組件setState()會調用;
父組件props改變會調用;
父組件經過forceUpdate從新執行render,也會調用當前組件的shouldComponentUpdate;
其實和componentWillMount相似,
這個方法也應該儘可能避免使用,將要被遺棄。幾乎用不上。應該都統一到componentDidUpdate中去處理。
setState(),props發生改變,父組件從新render都會調用。發生在更新狀態的render以後,這時候已經能夠讀取dom了。一般用於處理滾動位置的聊天線程等UI中。
和getDerivedStateFromProps同樣它返回一個對象來更新狀態,若是返回的是null就表示不更新任何內容
它能夠作的,不要作的同componentDidUpdate同樣
setState(),props發生改變,父組件從新render都會調用。這個方法相對用得也比較多。同componentDidMount處理事件函數相似,若是組件被更新的時候,原有的內容被從新繪製後可能也須要再次處理事件函數。
componentDidUpdate(prevProps, prevState) { if(prevProps.oneProp !== this.props.oneProp) { // 若是有變化,在這裏作一些異步請求,可能會在異步請求的回調函數裏setState // 不要直接去執行this.setState } }
當react組件要從dom樹上刪除掉的時候,這個方法就會被調用。
若是在componentDidMount中使用非React的方法創造了一些DOM元素,若是撒手無論可能會形成內存泄漏,那就須要在componentWillUnmount中把這些創造的DOM元素清理掉。
應用場景:清理定時器,關閉socket, 清除監聽器等
import React, { Component } from "react"; export default class LifeCycle extends Component { state = { } static getDerivedStateFromProps(props, state) { } componentDidMount = () => { } shouldComponentUpdate = (nextProps, nextState) => { } getSnapshotBeforeUpdate = (prevProps, prevState) => { } componentDidUpdate = (prevProps, prevState) => { } componentWillUnmount = () => { } render() { return ( <div> </div> ) } }