組件的生命周期
組件在react的生命周期中主要經(jīng)歷三個階段:實例化、存在期和銷毀時蜻懦。
React.js在組件生命周期的每個階段暴露接口或掛鉤方法间螟。
實例化
當組件在客戶端被實例化,第一次被創(chuàng)建時逸吵,以下方法依次被調(diào)用:
1凶硅、getDefaultProps
2、getInitialState
3扫皱、componentWillMount
4足绅、render
5、componentDidMount
當組件在服務端被實例化韩脑,首次被創(chuàng)建時氢妈,以下方法依次被調(diào)用:
1、getDefaultProps
2段多、getInitialState
3首量、componentWillMount
4、render
componentDidMount 不會在服務端被渲染的過程中調(diào)用进苍。
getDefaultProps
var U serInformation = React.createClass({
getDefaultProps: function() {
return {
name: 'Nobody',
score: 0
}
}
});
在創(chuàng)建組件的任何實例之前加缘,只調(diào)用getDefaultProps()方法一次。 所以你應該避免在getDefaultProps()方法中使用this.props觉啊。其返回的對象可以用于設置默認的 props(properties的縮寫) 值拣宏。
getInitialState
const userScore = [
{
name: 'Tom',
score: 55
},
{
name: 'Jerry',
score: 80
}
]
var UserInformation = React.createClass({
getInitialState: function() {
return {
players: userScore
}
},
});
初始化組件的 state 的值,其返回值會賦值給組件的 this.state 屬性杠人。getInitialState()方法僅在實例化組件之前調(diào)用一次勋乾。
componentWillMount
服務器端和客戶端都只調(diào)用一次,在初始化渲染執(zhí)行之前立刻調(diào)用嗡善。
它也是在組件WillMount()中設置初始狀態(tài)值的好地方市俊。
class UserInformation extends React.Component {
componentWillMount() {
this.setState({
isPassed: this.props.score >= 60
});
alert('componentWillMount => ' + this.props.name);
console.log('componentWillMount => ' + this.props.name);
}
// ...
}
render
該方法會創(chuàng)建一個虛擬DOM,用來表示組件的輸出滤奈。對于一個組件來講摆昧,render方法是唯一一個必需的方法。render方法需要滿足下面幾點:
- 只能通過 this.props 和 this.state 訪問數(shù)據(jù)(不能修改)
- 可以返回 null,false 或者任何React組件
- 只能出現(xiàn)一個頂級組件蜒程,不能返回一組元素
- 不能改變組件的狀態(tài)
- 不能修改DOM的輸出
根據(jù) state 的值绅你,生成頁面需要的虛擬 DOM 結(jié)構(gòu)伺帘,并返回該結(jié)構(gòu)。
componentDidMount
在渲染完成后調(diào)用此方法忌锯,此時的DOM已為真實DOM伪嫁,可以再該方法中通過 this.getDOMNode() 訪問到真實的 DOM(推薦用ReactDOM.findDOMNode())。
class Scroll extends React.Component {
constructor(props) {
super(props);
this._handleScroll = this.handleScroll.bind(this);
}
handleScroll() {}
componentDidMount() {
alert('componentDidMount in NoticeBoard');
window.addEventListener('scroll', this._handleScroll);
}
// ...
}
由于組件并不是真實的 DOM 節(jié)點偶垮,而是存在于內(nèi)存之中的一種數(shù)據(jù)結(jié)構(gòu)张咳,叫做虛擬 DOM (virtual DOM)。只有當它插入文檔以后似舵,才會變成真實的 DOM 脚猾。有時需要從組件獲取真實 DOM 的節(jié)點,這時就要用到 ref 屬性砚哗。
需要注意的是龙助,由于 this.refs.[refName] 屬性獲取的是真實 DOM ,所以必須等到虛擬 DOM 插入文檔以后蛛芥,才能使用這個屬性提鸟,否則會報錯。
存在期
此時組件已經(jīng)渲染好并且用戶可以與它進行交互仅淑,比如鼠標點擊称勋,手指點按,或者其它的一些事件涯竟,導致應用狀態(tài)的改變铣缠,你將會看到下面的方法依次被調(diào)用
1、componentWillReceiveProps
2昆禽、shouldComponentUpdate
3、componentWillUpdate
4蝇庭、render
5醉鳖、componentDidUpdate
componentWillReceiveProps
當組件接收到新的 props 時,會觸發(fā)該函數(shù)哮内。在改函數(shù)中盗棵,通常可以調(diào)用 this.setState 方法來完成對 state 的修改北发。
class App extends React.Component {
componentWillReceiveProps(nextProps) {
// Calculate state according to props changes
this.setState({
isPassed: nextProps.score
});
}
}
shouldComponentUpdate
在接收到新的props或state時纹因,將在渲染之前調(diào)用該函數(shù)。 在初始渲染時不會調(diào)用此方法琳拨。
shouldComponentUpdate()默認情況下返回true瞭恰。
這種方法通常是一個機會,以防止考慮性能的不必要的渲染狱庇。 只要讓shouldComponentUpdate()返回false惊畏,那么組件的render()方法將被完全跳過恶耽,直到下一個props或state發(fā)生更改。
class App extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
// Don't rerender if score doesn't change,
if ( nextProps.score == this.props.score ) {
return false;
}
return true;
}
}
componentWillUpdate
這個方法和 componentWillMount 類似颜启,在組件接收到了新的 props 或者 state 即將進行重新渲染前偷俭,componentWillUpdate(object nextProps, object nextState) 會被調(diào)用,注意不要在此方面里再去更新 props 或者 state缰盏。
componentDidUpdate
這個方法和 componentDidMount 類似涌萤,在組件的更新刷新到DOM后componentDidUpdate(object prevProps, object prevState) 會被調(diào)用。 這種方法不是初始渲染的方法口猜「合可以在這里訪問并修改 DOM。
銷毀時
componentWillUnmount
在組件被卸載或從DOM中移除之前立即調(diào)用暮的。
使用它作為執(zhí)行清理操作的機會笙以。 例如,在此處解除綁定事件冻辩、銷毀無效偵聽器以避免內(nèi)存泄漏猖腕。
class App extends React.Component {
componentWillUnmount() {
window.removeEventListener('scroll', this._handleScroll);
}
}