在組件的整個生命周期中,隨著該組件的props或者state發生改變,它的DOM表現也將有相應的改變,一個組件就是一個狀態機,對于特定的輸入,它總會返回一致的輸出。
React為每個組件提供了生命周期鉤子函數去響應不同的時刻——創建時、存在期及銷毀時
實例化:
一個實例出吃被穿件時所調用的生命周期方法與其他哥哥后續實例被創建所調用的方法略有不同。當你首次使用一個組建類時,會看到下面這些方法依次被調用:
getDefaultProps
getInitialState
componentWillMount
render
ComponentDidMOunt
對于該組件類所有后續應用,你將會看到下面的方法依次被調用。注意:gerDefaultProps方法不在列表中。
getInitialState
componentWillMount
render
componentDidMount
存在期:
隨著應用狀態的改變,以及組件逐漸受到影響,你將會看到下面的方法一次被調用:
componentwillReceiveProps
shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate
銷毀&清理期:
最后,當該組件被使用完成后,componentWillUnmount方法會被調用,目的是給這個實例提供清理自身的機會。
以下是詳細說明:
實例化:
當每個新的組件被創建首次渲染時,有一系列的方法可以用來為其做準備工作,這些方法中的每一個斗毆明確的職責,如下所示:
getDefaultProps
對于組件來說,這個方法只會調用一次,對于那些沒有父輩組件指定的props屬性的新建實例來說,這個方法返回的對象可用與為實例設置默認的props值。
getInitalState:
對于組件的每個實例來說,這個方法調用次數有且僅有一次,這里你將有機會初始化每個實例的state,與getDefaultProps方法不同的是,每次實例創建時該方法都會被調用一次,這個方法中,可以訪問到this.props.
componentWillMount:
該方法在完成首次渲染之前被調用,這也是在render方法調用前可以修改組件state的最后一次機會。
render:
在這里你創建一個虛擬DOM,用來表示組件的輸出,對于一個組件來說,render是唯一一個必需的方法,并且有特定的規則。render方法選要滿足下面幾點:
只能通過this.props和this.state訪問數據。
可以返回null,false或者任何React組件。
只能出現一個頂級組件(不能返回一組元素)、
必須純凈,有位置不能改變組件狀態或者修改DOM輸出。
componentDidMount:
在render方法成功調用并且真實的DOM已經被渲染之后,可以在componentDidMount內部通過this.getDOMNode(方法訪問到它。
這就是你可以訪問原始DOM的生命周期的鉤子函數,當你需要測量DOM元素的高度或者使用計時器操作它或者運行jQuery插件時,可以將這些操作掛載到這個方法上:
舉例來說,假設需要在一個通過React渲染出的表單元素上使用jQueryUI的Autocomplete插件,則可以這樣使用它:
//需要自動補全的字符串列表
var datasource =[...];
var MyComponent=React.crateClass({
render:function(){
rerurn <input .../>
},
componentDidMount:function(){
$(this.gerDOMNode()).autocomplete({
source:datasource
});
}
});```
ps:當React運行在服務器端時候,componentdidmount方法不會被調用。
存在期:
此時組件已經渲染好并且用戶可以與它進行交互,通常一次鼠標點擊、手指點按或者鍵盤事件觸發一個時間處理器,隨著用戶改變了組件或則和整個應用的state,便會有新的state流入組件樹,并且我們將會獲得操控它的機會。
componentWillReceiveProps:
任何時刻組件的props都可以通過父輩組件來更改,出現這種情況時,componentWillReceiveProps方法會被調用,你將獲得更改props方法及跟他關心state的機會。例如:
```componentWillReceiveProps:function(nextProps){
if(nextProps.checked !==undefined){
this.setState({
checked:nextProps.checked
});
}
}```
shouleComponentUpdate:
調用shoulecomponentUpadte方法在組件渲染時進行精確優化。如果某個組件或者它的任何子組件不需要渲染成新的props或則和state,則該方法返回false,返回false則是說明React要跳到render方法,一屆位于render前后的鉤子函數:componentWillUpadate和componentDidUpdate。
該方法非必需的,并且大部分情況沒有必要使用它。
componentWillUpdate:
和componentwillMount:方法類似,組建會在收到新的props或者state進行渲染之前調用該方法。
注意:你不可以在該方法中更新huo或者props。而應該借助componentWillreceiveProps方法在運行時更新state。
componentDidUpdate:
和componentDidMount方法類似,該方法給我們更新已經渲染好的DOM機會。
銷毀&清理期
當React使用完一個組件,這個組件必須從DOM中卸載隨后被銷毀。此時僅有的一個狗子函數會做出響應,完成所有的清理和銷毀工作。
componentWillUnmount:
最后,隨著組件從他的層級結構中移除,這個組件的生命也就走id熬了盡頭,該方法會在組件被移除之前調用,讓你有機會做一些清理工作。在componentDidMount方法中添加的所有任務都需要在該方法中撤銷,比如穿件的定時器或者添加的事件監聽器。
反模式:把計算后的值賦值給state:
getInitalState方法中,嘗試通過this.props來創建state的做法是一種反模式。React專注于維護數據的單一來源。它的設計使得傳遞數據的來源更加顯而易見,這激素和iReact的一個優勢。
比如在組件中吧日期轉化成字符串形式,或者渲染之前字符串轉換為大寫。這些都不是state,只能夠在渲染時進行計算。
當組件的state值和它基于的prop不同步,因而無法了解到render函數內部結構時,可以認定為一種反模式。
//反模式:經過計算后值不應該賦給state
```getDefaultProps:function(){
return{
date:newDate()
};
},
getInitalState:function(){
return{
day:this.props.date.getDay()
}
},
render:function(){
return <div>Day:{this.state.day}</day>
}```
正確的模式應該是渲染時計算這些值,保證了計算后的值永遠不會派生出它的props值不同步。
```//渲染時計算值是正確的
gerDefaultProps:function(){
return{
date:new Date()
};
}
render:function(){
var day = this.props.date.getDay();
return <div>Day:{day}</div>;
}```
然而,如果你的目的并不是同步,而只是簡單的初始化state,那么在getInitialState方法中使用props是沒問題的,只是一定要明確你的意圖,比如prop添加initial前綴。
```getDefaultProps:function(){
return{
initialValue:'some-dafault-value'
};
},
getInitialState:function(){
return{
value:this.props.initialValue
};
},
render:function(){
return <div>{this.props.value}</div>
}```
總結:
react生命周期提供了進行設計的鉤子函數,會伴隨著組件整個生命周期。和狀態機類似,每個組件都被設計成了能夠在整個生命周期中輸出穩定、語義化的標簽。
組件不會獨立存,隨著父組件將props推送給他們的子組件,以及那些子組件渲染它們自身的子組件你必須謹慎的考慮數據是如何流經整個應用的。。