有關React生命周期:
1、組件生命周期的執行次數是什么樣子的???
只執行一次: constructor、componentWillMount、componentDidMount
執行多次:render 、子組件的componentWillReceiveProps、componentWillUpdate、componentDidUpdate
有條件的執行:componentWillUnmount(頁面離開,組件銷毀時)
不執行的:根組件(ReactDOM.render在DOM上的組件)的componentWillReceiveProps(因為壓根沒有父組件給傳遞props)
2、組件的生命周期執行順序是什么樣子的???
假設組件嵌套關系是 App里有parent組件,parent組件有child組件。
如果不涉及到setState更新,第一次渲染的順序如下:
App: constructor --> componentWillMount --> render --> parent: constructor --> componentWillMount --> render --> child: constructor --> componentWillMount --> render --> componentDidMount (child) --> componentDidMount (parent) --> componentDidMount (App)
這時候觸發App的setState事件
App: componentWillUpdate --> render --> parent: componentWillReceiveProps --> componentWillUpdate --> render --> child: componentWillReceiveProps --> componentWillUpdate --> render --> componentDidUpdate (child) --> componentDidUpdate (parent) --> componentDidUpdate (App)
那如果是觸發parent的setState呢?
parent: componentWillUpdate --> render --> child: componentWillReceiveProps --> componentWillUpdate --> render --> componentDidUpdate (child) --> componentDidUpdate (parent)
那如果是只是觸發了child組件自身的setState呢?
child: componentWillUpdate --> render --> componentDidUpdate (child)
結論:
1、如圖:完成前的順序是從根部到子部,完成時時從子部到根部。(類似於事件機制)
2、每個組件的紅線(包括初次和更新)生命周期時一股腦執行完畢以后再執行低一級別的紅線生命周期。
3、第一級別的組件setState是不能觸發其父組件的生命周期更新函數,只能觸發更低一級別的生命周期更新函數。
總結起來就如下圖:
提問:那么這里提一個問題,如果App里面有多個parent1 parent2 ...,parent里由多個child,那么生命周期執行順序應該時什么樣的????
結論:一套組件(父包括子,子包括孫)執行的時候一個整體,執行完畢在執行下一套,用到這里就是App里先執行parent1和parent1的子,子的子。。。,然后完畢再執行parent2這一套。
3、什么時候該用componentWillReceiveProps?
是否每個子組件都需要componentWillReceiveProps生命周期函數來更新數據嗎? 你的原則是??
A、開始前首先需要知道componentWillReceiveProps函數有一個參數nextProps,它是一個 { 對象 } ,從單詞就可以看出它是update時候(也就是下一次)父組件傳遞過來的props。
B、還要知道 "第一條中" 所講解的有些生命周期函數只執行一次,而有的執行多次,其中componentWillReceiveProps執行多次,而constructor等執行一次。
C、還需知道在子組件中每次傳遞過來的this.props對象其實和componentWillReceiveProps的nextProps是一樣的,都是最新的。
D、由"第一條"得知: componentWillReceiveProps生命周期是在更新子組件最先執行的,優先於compoentWillUpdate,更優先於render。
E、render函數里不能使用setState(),否則會造成死循環。
那么知道了以上呢?
由C得知, this.props 和 componentWillReceiveProps的nextProps都是一樣的,通過this.props就可以取到最新的值, 那么componentWillReceiveProps還有必要嗎?
所以:大部分情況下 componentWillReceiveProps 生命周期函數是沒用的,即可以略去不寫,因為它確實沒什么用。
但是情況1:
由D得知,componentWillReceiveProps是最先執行的,所以在其內可以setState({}),在接下來的render中能拿到最新的state后值,再加上B得知,
如果是下面這種情況: 在constructor函數中初始化了某個state,必須用 componentWillReceiveProps 來更新state,以便render中為新的state值。
情況2:
如果父組件有一些請求,每次參數更新的時候才發請求,同時和子組件的關系比較密切,
可以將數據請求放在componentWillReceiveProps進行執行,需要傳的參數則從(nextProps)中獲取。
而不必將所有的請求都放在父組件中,於是該請求只會在該組件渲染時才會發出,從而減輕請求負擔。
情況3:
watch監聽props值變化,對子組件進行處理,比如:當傳入的props.value發生變化,執行一些動作。
如果你接觸過vue,會知道vue中有一個關於watch的選項,是根據setter獲取新舊值,進行動作的執行
而react中最合適做watch的時機是在componentWillReceiveProps中
componentWillReceiveProps(nextProps) { // this.props中的值是舊值 // nextProps中的值是新值 const { value: oldValue } = this.props; const { value: newValue } = nextProps; if (newValue !== oldValue) { // TODO... } }
結論: 大部分情況下 componentWillReceiveProps 生命周期函數是沒用的,即可以略去不寫,
但是在constructor函數中初始化了某個state,必須用 componentWillReceiveProps 來更新state,不可省去,否則render中的state將得不到更新。
同時如果您想在子組件監聽watch值變化做處理,也可以用到componentWillReceiveProps
注意:使用componentWillReceiveProps的時候,不要去向上分發,調用父組件的相關setState方法,否則會成為死循環。