首先, 當面對一些問題:html
1 React 用了這麼久,常常遇到的問題是setState
在這裏寫合適嗎?react
2 爲何setState
寫在這裏形成了重複渲染屢次?git
3 爲何你的setState
用的這麼亂?github
4 組件傳入props
是更新呢?從新掛載呢?仍是怎樣?面試
5 ...redux
其次, 生命週期能夠看到整個Component的運行過程, 在coding的時候很天然的找好他們的位置, 合做起來就會方便多了,這裏極力推薦airbnb的react coding 規範.服務器
因此整理了這篇文章。若是錯誤,歡迎指正。網絡
componentWillMount()
執行場景session
在render()
方法以前異步
解釋
1 由於componentWillMount是在render以前執行,因此在這個方法中setState
不會發生從新渲染(re-render);
2 這是服務端渲染(server render
)中惟一調用的鉤子(hook);
3 一般狀況下,推薦用constructor()
方法代替;
render()
執行場景
1 在componentWillMount()
方法以後
2 在componentWillReceive(nextProps, nextState)
方法以後
解釋
==
componentDidMount()
執行場景
在render()
方法以後
解釋
1 這個方法會在render()以後當即執行;
2 這裏能夠對DOM進行操做,這個函數以後ref變成實際的DOM(@TODO 表述可能不清晰);
3 這裏能夠加載服務器數據,而且若是使用了redux之類的數據服務,這裏能夠出發加載服務器數據的action;
4 這裏可使用setState()
方法觸發從新渲染(re-render)
;
componentWillReceiveProps(nextProps)
執行場景
在已經掛在的組件(mounted component)接收到新props時觸發;
簡單的說是在除了第一次生命週期(componentWillMount -> render -> componentDidMount)以後的生命週期中出發;
解釋
1 若是你須要在props
發生變化(或者說新傳入的props)來更新state
,你可能須要比較this.props
和nextProps
, 而後使用this.setState()
方法來改變this.state
;
注意
1 React可能會在porps傳入時即便沒有發生改變的時候也發生從新渲染, 因此若是你想本身處理改變,請確保比較props當前值和下一次值; 這可能形成組件從新渲染;
2 若是你只是調用this.setState()
而不是從外部傳入props
, 那麼不會觸發componentWillReceiveProps(nextProps)
函數;這就意味着: this.setState()
方法不會觸發componentWillReceiveProps()
, props
的改變或者props
沒有改變纔會觸發這個方法;
shouldComponentUpdate(nextProps, nextState)
執行場景
在接收到新props
或state
時,或者說在componentWillReceiveProps(nextProps)
後觸發
解釋
在接收新的props
或state
時肯定是否發生從新渲染,默認狀況返回true
,表示會發生從新渲染
注意
1 這個方法在首次渲染時或者forceUpdate()
時不會觸發;
2 這個方法若是返回false
, 那麼props
或state
發生改變的時候會阻止子組件發生從新渲染;
3 目前,若是shouldComponentUpdate(nextProps, nextState)
返回false
, 那麼componentWillUpdate(nextProps, nextState)
, render()
, componentDidUpdate()
都不會被觸發;
4 Take care
: 在將來,React可能把shouldComponentUpdate()
當作一個小提示(hint)而不是一個指令(strict directive),而且它返回false
仍然可能觸發組件從新渲染(re-render);
Good Idea
在React 15.3之後, React.PureComponent
已經支持使用,我的推薦,它代替了(或者說合並了)pure-render-mixin
,實現了shallowCompare()
。擴展閱讀
componentWillUpdate(nextProps, nextState)
執行場景
在props
或state
發生改變或者shouldComponentUpdate(nextProps, nextState)
觸發後, 在render()
以前
解釋
1 這個方法在組件初始化時不會被調用;
注意
1 千萬不要在這個函數中調用this.setState()
方法.;
2 若是確實須要響應props
的改變,那麼你能夠在componentWillReceiveProps(nextProps)
中作響應操做;
3 若是shouldComponentUpdate(nextProps, nextState)
返回false
,那麼componentWillUpdate()
不會被觸發;
componentDidUpdate(prevProps, prevState)
執行場景
在發生更新或componentWillUpdate(nextProps, nextState)
後
解釋
1 該方法不會再組件初始化時觸發;
2 使用這個方法能夠對組件中的DOM進行操做;
3 只要你比較了this.props
和nextProps
,你想要發出網絡請求(nextwork requests)時就能夠發出, 固然你也能夠不發出網絡請求;
注意
若是shouldComponentUpdate(nextProps, nextState)
返回false
, 那麼componentDidUpdate(prevProps, prevState)
不會被觸發;
componentWillUnmount()
執行場景
在組件卸載(unmounted)或銷燬(destroyed)以前
解釋
這個方法可讓你處理一些必要的清理操做,好比無效的timers、interval,或者取消網絡請求,或者清理任何在componentDidMount()
中建立的DOM元素(elements);
setState(Object/Function)
解釋
經過事件(event handlers)或服務請求回調(server request callbacks), 觸發UI更新(re-render);
參數
1 能夠是Object
類型, 這時是異步的setState, 同時接收一個在state發生改變以後的回調, 如this.setState(Object, callback)
, 其中callback能夠是() => { ... this.state ... }
;
2 能夠是Function
類型, 這時是同步的setState, 例如: (prevState, prevProps) => nextState
, 同步存在必定效率問題(不理解), 可是它有一個好處就是支持Immutable
;
緣由
組件第一次創建
觸發
componentWillMount -> render -> componentDidMount
緣由
props
發生改變
觸發
componentWillReceiveProps -> shouldComponentUpdate -> componentWillUpdate -> componentDidUpdate
緣由
this.setState()
使state
發生改變
觸發
shoudlComponentUpdate -> componentWillUpdate -> componentDidUpdate
緣由
組件卸載或銷燬
觸發
componentWillUnmount