2016-05-24 41 views
1

如果我理解正確,組件的React生命週期應確保在componentWillReceiveProps之前調用componentDidMount。當我在一個組件的初始安裝上測試它時,它似乎以這種方式工作。但是,當組件已經被安裝並重新安裝時,順序是相反的。這是預期的行爲?下面這段代碼說明了可以引入這樣一個潛在的bug: 生命週期:componentWidReceiveProps在組件之前調用

class Example extends React.Component { 
    componentDidMount() { 
     this.something = { foo: 'bar' }; 
    } 
    componentWillReceiveProps(nextProps) { 
     this.something.foo; 
     // Throws a TypeError if this code is reached before 
     // componentDidMount is called. 
    } 
} 
+1

您能分享您的測試牀嗎?無論如何,在裝配時不會調用'componentWillReceiveProps'。稍後,它會在收到新的道具時調用。但是'componentDidMount'根本不會被調用,除非組件已經被首先卸載。 – hazardous

回答

6

簡短的回答
射擊這些方法的順序確實不能保證。這就是爲什麼(在你的例子中)使用道具和狀態之外的組件變量不是一個好主意的原因之一。

更好:如果您需要在生命週期事件之外使用它,請將您的{ foo: 'bar' }置於狀態。

較長的答案

componentDidMount()只調用一次每個生命週期:

  • 第一渲染(NB後:畢竟孩子還呈現了,畢竟孩子還呼籲他們的componentDidMount s)
  • 如果組件已被卸載後(但這確實是一個新的生命週期)

componentWillReceiveProps()不會在生命週期中的第一次渲染時調用,但會在父級再次發送道具時在所有後續渲染上調用。

正常情況下,第二個渲染(觸發)componentWillReceiveProps會在組件(及其子組件)完成安裝後發生,因此在componentDidMount()之後。

但我至少能想到1(或許理論上的)場景,該訂單將逆轉:

  1. 組件接收道具,並開始呈現。
  2. 組件正在渲染時,但尚未完成渲染,組件接收新的道具。
  3. componentWillReceiveProps()被激發,(但componentDidMount還沒有啓動)
  4. 本身已呈現完畢所有兒童和組件後,componentDidMount()將閃光。

所以componentDidMount()不是初始化組件變量如{ foo: 'bar' }的好地方。
componentWillMount()將是一個更好的生命週期事件。
不過,我會勸阻任何使用的組件範圍變量裏面反應的組分,並堅持的設計原則:

  • 所有組成變量應該住在任一狀態或道具(和是不可變的)
  • 所有其他變量受到生命週期方法的限制(並且不會超出該範圍)