一、react-native的生命周期
1. getDefaultProps
在組件創(chuàng)建之前,會(huì)先調(diào)用 getDefaultProps() ,全局調(diào)用一次,嚴(yán)格地來(lái)說(shuō),這不是組件的生命周期的一部分。在組件被創(chuàng)建并加載候,首先調(diào)用 getInitialState() ,來(lái)初始化組件的狀態(tài)。
2. componentWillMount
準(zhǔn)備加載組件
3. render
加載組件
4. componentDidMount
組件第一次加載完成后調(diào)用
5. componetWillReceiveProps
當(dāng)組件收到新的屬性,調(diào)用此方法
6. shouldComponentUpdate
這個(gè)函數(shù)的返回值決定是否需要更新組件,如果 true 表示需要更新,繼續(xù)走后面的更新流程。否者,則不更新,直接進(jìn)入等待狀態(tài)。
默認(rèn)情況下,這個(gè)函數(shù)永遠(yuǎn)返回 true 用來(lái)保證數(shù)據(jù)變化的時(shí)候 UI 能夠同步更新。在項(xiàng)目中,你可以自己重載這個(gè)函數(shù),通過(guò)檢查變化前后屬性和狀態(tài),來(lái)決定 UI 是否需要更新,能有效提高應(yīng)用性能。
7. componentWillUpdate
當(dāng)組件狀態(tài)或者屬性改變,并且上面的 shouldComponentUpdate(...) 返回為 true ,就會(huì)開始準(zhǔn)更新組件,并調(diào)用 componentWillUpdate()。
需要特別注意的是,在這個(gè)函數(shù)里面,你就不能使用 this.setState 來(lái)修改狀態(tài)。這個(gè)函數(shù)調(diào)用之后,就會(huì)把 nextProps 和 nextState 分別設(shè)置到 this.props 和 this.state 中。緊接著這個(gè)函數(shù),就會(huì)調(diào)用 render() 來(lái)更新界面了。
8. componentDidUpdate
在render()之后調(diào)用此方法來(lái)得到通知
9. componentWillUnmount()
當(dāng)組件要被界面移除時(shí),調(diào)用此方法。在這個(gè)方法可以做相關(guān)清理工作。
二、props和state
props、state共同來(lái)控制組件數(shù)據(jù)。props是在父組件中指定,而且一經(jīng)指定,在被指定的組件的生命周期中則不再改變。 對(duì)于需要改變的數(shù)據(jù),我們需要使用state。
- props:大多數(shù)組件在創(chuàng)建時(shí)就可以使用各種參數(shù)來(lái)進(jìn)行定制。用于定制的這些參數(shù)就稱為props(屬性)。屬性定義時(shí)要將屬性名掛載在this.props對(duì)象上,其他組件調(diào)用該組件時(shí),需要指定該屬性的value。
使用示例:
//在被調(diào)用組件中,定義property屬性
export default class PropertyView extends Component{
render(){
var property =this.props.property;
var stats= property.bedroom_number+'bed'+property.property_type;
if (property.bathroom_number){
stats+=', '+property.bathroom_number+' '+(property.bathroom_number>1
?'bathrooms':'bathroom');
}
var price =property.price_formatted.split(' ')[0];
return(
<View style={styles.container}>
<Image style={styles.image}
source={{uri:property.image_url}}
/>
<View style={styles.heading}>
<Text style={styles.price}>£{price}</Text>
<Text style={styles.title}>{property.title}</Text>
<Text style={styles.description}>{property.summary}</Text>
</View>
</View>
)
}
}
//調(diào)用組件中為property屬性賦值
this.props.navigator.push({
title:"PropertyView",
component:PropertyView,
passProps:{
property:property
}
});
- state:在constructor中初始化state,然后在需要修改時(shí)調(diào)用setState方法。
使用示例:
//在constructor中初始化
constructor(props) {
super(props);
this.state = {
message: ''
};
}
//在需要更新數(shù)據(jù)的位置
this.setState({
message: 'there was a problem with obtaining your location: ' + error
});
三、navigator
安卓中使用Navigator,IOS使用NavigatorIOS
使用示例:
1.在父組件render()中
render() {
return (
<Navigator
initialRoute={{
title:'Property Finder'
}}
renderScene={(route,navigator)=>{
return<SearchPage/>
}}
/>
);
}
2.在子組件中使用this.props.navigator獲得navigator,
并且可以通過(guò)push和pop方法來(lái)推入或彈出component
this.props.navigator.push({
title: 'Results',
component: SearchResults,
passProps: {
//向要推入組件傳遞數(shù)據(jù)
listings: response.listings
}
});
四、ListView
- dataSource:列表的數(shù)據(jù)源
- renderRow:逐個(gè)解析數(shù)據(jù)源中的數(shù)據(jù),然后返回一個(gè)設(shè)定好格式的組件來(lái)渲染。
- rowHasChanged:必須屬性,比較兩個(gè)item數(shù)據(jù)
使用示例:
class ListViewBasics extends Component {
// 初始化模擬數(shù)據(jù)
constructor(props) {
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows([
'John', 'Joel', 'James', 'Jimmy', 'Jackson', 'Jillian', 'Julie', 'Devin'
])
};
}
render() {
return (
<View style={{flex: 1, paddingTop: 22}}>
<ListView
dataSource={this.state.dataSource}
renderRow={(rowData) => <Text>{rowData}</Text>}
/>
</View>
);
}
}
五、學(xué)習(xí)中遇到的問(wèn)題
1.在切換React-native項(xiàng)目時(shí),一定要關(guān)閉上一個(gè)項(xiàng)目的react packager服務(wù)窗口,否則會(huì)出現(xiàn)如下錯(cuò)誤:
Application xxxx has not been registered.This is either due to a require() error during initialization or failure to call AppRegistry.registerComponent.
2.相比Java,JavaScript在出現(xiàn)語(yǔ)法錯(cuò)誤和bug時(shí),更不容易定位到錯(cuò)誤位置,因此在編寫JavaScript時(shí)一定要更加的細(xì)心。