@linux1s1s
2017-03-10T13:59:44.000000Z
字数 3446
阅读 1891
React-Native
2017-03
我们接着React-Native Primary Flex布局这篇博客继续往下看基本组件,然后会有个UI和网络协调工作的Demo
关于Fetch的详细用法可以参考Promise和传统 Ajax 已死,Fetch 永生,这里仅仅给个示例,不再详解。
var REQUEST_URL = 'https://raw.githubusercontent.com/facebook/react-native/master/docs/MoviesExample.json';
fetchData() {
fetch(REQUEST_URL, {
method: 'GET'
})
.then((response) => response.json())
.then((responseData) => {
this.setState({
movies: responseData.movies,
});
})
.catch((error) => {
callback(error);
});
}
这里补充一下Json
我们从这里的解析可以看到,相比Native的Json解析,这里天然融合了字符串和POJO,而且在操作这个POJO的时候也极其方便。
关于Flex布局的部分在React-Native Primary Flex布局这篇博客已经有详细说明,这里将Flxe布局和上面讲到的Fetch网络请求融合在一起,做个简单的数据驱动更新UI的小Demo,该Damo参考React Native网络请求及UI展示,有部分改动,特此说明。
import React, {Component} from 'react';
import {AppRegistry, StyleSheet, Image, Text, View} from 'react-native';
var REQUEST_URL = 'https://raw.githubusercontent.com/facebook/react-native/master/docs/MoviesExample.json';
const styles = StyleSheet.create({
/**
* 最外层容器,定义内层容器的布局方向,这里是横向
*/
container: {
flex: 1, flexDirection: 'row', justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF'
},
/**
* 内层容器,左边容器,flex:1 和Android的weight相似
*/
leftContainer: {
flex: 1
},
/**
* 内层容器,中间容器,flex:1 和Android的weight相似
*/
middleContainer: {
flex: 1
},
/**
* 内层容器,右边容器,flex:1 和Android的weight相似
*/
rightContainer: {
flex: 1
},
/**
* Item,海报图布局定义
*/
thumbnail: {
alignItems: 'center',
width: 100,
height: 80,
marginLeft: 5,
marginRight: 5,
},
/**
* Item,电影名称布局定义
*/
title: {
fontSize: 20, marginBottom: 8, textAlign: 'center'
},
/**
* Item,上映年份布局定义
*/
year: {
fontSize: 18,
textAlign: 'center'
},
});
/**
* 定义一个组件NwesomeProject,此名字必须与工程名一致
props:(1)大多数组件在创建时要设置各种参数,用于定制的这些参数就叫属性props
(2)比如Image设置source={pic},pic为图片网络或本地路径,比如自定义的属性
(3)与state相比,props是在父组件中指定,并且一经指定不可更改。
state:state是用来监控状态改变,进而自动刷新页面的组件,我们将movies放入state中,表示从网络加载数据,数据返回后会触发setState方法修改movies的内容,这时候对应UI监控state的地方会自动刷新,重新执行,达到UI刷新的目的。
*/
class NwesomeProject extends Component {
constructor(props) {
super(props);
this.state = {
movies: null,
};
}
/**
* render方法用于返回组件创建的UI对象,根据state的movies来判断,如果movies没有东西,则调用renderLoadingView方法返回loading界面。
* @returns {XML}
*/
render() {
if (!this.state.movies) {
return this.renderLoadingView();
}
/**
* 将网络请求返回的movie传进来,初始化对应的View,Image,Text显示图片,文本信息。
*/
return (
<View style={styles.container}>
<View style={styles.leftContainer}>
<Image source={{uri:this.state.movies[0].posters.thumbnail}}
style={styles.thumbnail}/>
<Text style={styles.title}>{this.state.movies[0].title}</Text>
<Text style={styles.year}>{this.state.movies[0].year}</Text>
</View>
<View style={styles.middleContainer}>
<Image source={{uri:this.state.movies[1].posters.thumbnail}}
style={styles.thumbnail}/>
<Text style={styles.title}>{this.state.movies[1].title}</Text>
<Text style={styles.year}>{this.state.movies[1].year}</Text>
</View>
<View style={styles.rightContainer}>
<Image source={{uri:this.state.movies[4].posters.thumbnail}}
style={styles.thumbnail}/>
<Text style={styles.title}>{this.state.movies[4].title}</Text>
<Text style={styles.year}>{this.state.movies[4].year}</Text>
</View>
</View>
);
}
fetchData() {
fetch(REQUEST_URL, {
method: 'GET'
})
.then((response) => response.json())
.then((responseData) => {
this.setState({
movies: responseData.movies,
});
})
.catch((error) => {
callback(error);
});
}
/**
* 组件加载完毕后调用请求网络的方法。
*/
componentDidMount() {
this.fetchData();
}
/**
* renderLoadingView方法返回加载中的界面,包括一个View,View中嵌套Text,Text相当于iOS中的label
* @returns {XML}
*/
renderLoadingView() {
return (
<View style={styles.container}>
<Text>
正在加载电影数据......
</Text>
</View>
);
}
}
AppRegistry.registerComponent('NwesomeProject', () => NwesomeProject);