在Android中Activity有七個生命周期方法,ReactNative組件也不例外,合理調用這些生命周期方法是每個項目合理開發(fā)的關鍵。先來看看RN組件的生命周期方法流程圖:
開始介紹之前我們先看一下RN中如何在控制臺顯示打印的調試信息。
RN中通過console.log();可以用來打印調試信息,在需要調試的地方加入
console.log('需要顯示的具體信息');
即可。
運行程序后搖一搖手機
會出現(xiàn)以下菜單
選擇第二項Debug JS Remotely 。
打開瀏覽器并打開開發(fā)者控制臺,在控制臺窗口下即可查看輸出的信息,如下圖所示:
下面來分析生命周期方法
(1)getDefaultProps()
在組件創(chuàng)建之前,會先調用 getDefaultProps() ,這是全局調用一次,嚴格地來說,這不是組件的生命周期的一部分。在組件被創(chuàng)建并加載候,首先調用 getInitialState() ,來初始化組件的狀態(tài)。并且當你調用這個方法時會提示你
就是說如果需要定義默認屬性得通過
static defaultProps = {
};
方式來定義。
getInitialState也是這樣
所以如果要定義state建議在constructor(props) 中來初始化組件的狀態(tài)。
(2)componentWillMount()
這個函數(shù)調用時機是在組件創(chuàng)建,并初始化了狀態(tài)之后,在第一次繪制 render() 之前。可以在這里做一些業(yè)務初始化操作,也可以設置組件狀態(tài)。這個函數(shù)在整個生命周期中只被調用一次。
(3)componentDidMount()
在組件第一次繪制之后,會調用 componentDidMount(),通知組件已經(jīng)加載完成。這個函數(shù)調用的時候,其虛擬 DOM 已經(jīng)構建完成,你可以在這個函數(shù)開始獲取其中的元素或者子組件了。需要注意的是,RN 框架是先調用子組件的 componentDidMount(),然后調用父組件的函數(shù)。從這個函數(shù)開始,就可以和 JS 其他框架交互了,例如設置計時 setTimeout 或者 setInterval,或者發(fā)起網(wǎng)絡請求。這個函數(shù)也是只被調用一次。這個函數(shù)之后,就進入了穩(wěn)定運行狀態(tài),等待事件觸發(fā)。
(4)componentWillReceiveProps(nextProps)
如果組件收到新的屬性(props),就會調用該方法。參數(shù) nextProps 是即將被設置的屬性,舊的屬性還是可以通過 this.props 來獲取。在這個回調函數(shù)里面,你可以根據(jù)屬性的變化,通過調用 this.setState() 來更新你的組件狀態(tài),這里調用更新狀態(tài)是安全的,并不會觸發(fā)額外的 render() 調用。
(5)shouldComponentUpdate(nextProps,nextState)
當組件接收到新的屬性和狀態(tài)改變的話,都會觸發(fā)調用該方法。參數(shù) nextProps 和上面的 componentWillReceiveProps 函數(shù)一樣,nextState 表示組件即將更新的狀態(tài)值。這個函數(shù)的返回值決定是否需要更新組件,如果 true 表示需要更新,繼續(xù)走后面的更新流程。否者,則不更新,直接進入等待狀態(tài)。
默認情況下,這個函數(shù)永遠返回 true 用來保證數(shù)據(jù)變化的時候 UI 能夠同步更新。在大型項目中,你可以自己重載這個函數(shù),通過檢查變化前后屬性和狀態(tài),來決定 UI 是否需要更新,能有效提高應用性能。
(6)componentWillUpdate(nextProps,nextState)
如果組件狀態(tài)或者屬性改變,并且上面的 shouldComponentUpdate(...) 返回為 true,就會開始準更新組件,并調用該方法。輸入?yún)?shù)與 shouldComponentUpdate 一樣,在這個回調中,可以做一些在更新界面之前要做的事情。需要特別注意的是,在這個函數(shù)里面,你就不能使用 this.setState 來修改狀態(tài)。這個函數(shù)調用之后,就會把 nextProps 和 nextState 分別設置到 this.props 和 this.state 中。緊接著這個函數(shù),就會調用 render() 來更新界面了。
(7)componentDidUpdate(prevProps,prevState)
調用了 render() 更新完成界面之后,會調用該方法來得到通知,因為到這里已經(jīng)完成了屬性和狀態(tài)的更新了,此函數(shù)的輸入?yún)?shù)變成了 prevProps 和 prevState。
(8)componentWillUnmount()
當組件要被從界面上移除的時候,就會調用 該方法。在這個函數(shù)中,可以做一些組件相關的清理工作,例如取消計時器、網(wǎng)絡請求等。
(9)constructor(props)
初始化時調用一次,并且是在componentWillMount()之前調用。
完整調試代碼如下:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
Alert,
Button,
View
} from 'react-native';
export default class LifeCycle extends Component {
constructor(props) {
console.log('constructor');
super(props);
this.state = {num: 1,}
}
// getDefaultProps(){
// console.log('getDefaultProps');
// }
// getInitialState(){
// console.log('getInitialState');
// }
componentWillMount(){
console.log('componentWillMount');
this.onButtonPressed=this._onButtonPressed.bind(this);
}
componentDidMount(){
console.log('componentDidMount');
}
componentWillReceiveProps(nextProps) {
console.log('componentWillReceiveProps');
}
shouldComponentUpdate(nextProps,nextState){
console.log('shouldComponentUpdate');
return true;
}
componentWillUpdate(nextProps,nextState){
console.log('componentWillUpdate');
}
componentDidUpdate(prevProps,prevState){
console.log('componentDidUpdate');
}
componentWillUnmount(){
console.log('componentWillUnmount');
}
_onButtonPressed(){
this.setState({num:this.state.num+1});
};
render() {
console.log('render');
return (
<View style={{margin:32}}>
<Button style={{width:512,height:48}}title="按鈕" color="#841584"onPress={this.onButtonPressed}/>
</View>
);
}
}
AppRegistry.registerComponent('LifeCycle', () => LifeCycle);