准备
开发环境搭建,请移步搭建开发环境
我们用Flexbox来布局。如果你想了解更多,可以读读这篇文章。
React中的各种生命周期方法请参阅此文档
ListView组件请参阅此文档
开发
我们会创建一个简单的Movies应用,它可以获取25个上映中的电影,然后把他们在一个ListView中显示。
译注:本文的示例代码采用了ES6语法,可能和其他文档写法不一致。但React Native从0.18之后,新建项目默认已经采用了ES6语法,故我们推荐不熟悉ES6与ES5区别的朋友先读读这篇文章,另外还可以看看阮一峰老师的书
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Image,
ListView,//引入ListView组件
} from 'react-native';
/*获取网络数据之前,可以先制造一些模拟数据练手,调整展现样式
*/
var MACKED_MOVIES_DATA=[
{title:'Title',year:'2016',posters:{thumbnail: 'http://i.imgur.com/UePbdph.jpg'}}
];
//拉取真正的数据,源url
var REQUEST_URL = 'https://raw.githubusercontent.com/facebook/react-native/master/docs/MoviesExample.json';
class SampleAppMovies extends Component {
constructor(props) {
super(props);
/*dataSource接口用来在ListView的整个更新过程中判断哪些数据行发生了变化。
你会注意到我们现在用到了this.state中的dataSource。
下一步就是在constructor生成的初始状态中添加一个空白的dataSource。
我们可以在state里用一个布尔型的属性(this.state.loaded)来判断数据加载是否已经完成了。
*/
this.state = {
dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
}),
loaded: false,
};
}
/*组件加载完毕之后,就可以向服务器请求数据。componentDidMount是React组件的一个生命周期方法,
它会在组件刚加载完成的时候调用一次,以后不再会被调用。*/
componentDidMount() {
this.fetchData();
}
/*为组件添加fetchData函数,你所需要做的就是在Promise调用链结束后执行this.setState({movies:data})。
在React的工作机制下,setState实际上会触发一次重新渲染的流程,
此时render函数被触发,发现this.state.movies不再是null。
注意我们在Promise调用链的最后调用了done() —— 这样可以抛出异常而不是简单忽略。*/
fetchData() {
fetch(REQUEST_URL)
.then((response) => response.json())
.then((responseData) => {
this.setState({
dataSource: this.state.dataSource.cloneWithRows(responseData.movies),
loaded: true,
});
})
.done();
}
render() {
if(!this.state.loaded){
return this.renderLoadingView();
}
return(
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderMovie}
style={styles.listview}
/>
);
}
renderLoadingView() {
return (
<View style={styles.container}>
<Text>
Loading movies...
</Text>
</View>
);
}
renderMovie(movie) {
return (
<View style={styles.container}>
<Image
source={{uri: movie.posters.thumbnail}}
style={styles.thumbnail}
/>
<View style={styles.rightContainer}>
<Text style={styles.title}>{movie.title}</Text>
<Text style={styles.year}>{movie.year}</Text>
</View>
</View>
);
}
}
/*创建单个电影样式对象
+---------------------------------+
|+-------++----------------------+|
|| || 标题 ||
|| 图片 || ||
|| || 年份 ||
|+-------++----------------------+|
+---------------------------------+
*/
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection:'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
thumbnail:{
width:53,
height:81,
},
rightContainer: {
flex:1,
},
title: {
fontSize: 20,
marginBottom: 8,
textAlign: 'center',
},
year: {
textAlign: 'center',
},
listView: {
paddingTop: 20,
backgroundColor: '#F5FCFF',
},
});
AppRegistry.registerComponent('SampleAppMovies', () => SampleAppMovies);