React Native项目实战之fetch请求并填充界面
fetch简介
在 AJAX 时代,进行请求 API 等网络请求都是通过XMLHttpRequest 或者封装后的框架进行网络请求。而在前端快速发展地过程中,为了契合更好的设计模式,产生了 fetch 框架。 fetch相比XMLHttpRequest,提供更加强大、高效的网络请求方式,所以在 Hybrid App 开发模式中,大量的用到了fetch框架作为网络请求。
fetch在浏览器中使用
在 Chrome 浏览器中已经全局支持了 fetch 函数,打开调试工具,在 Console 中可以进行体验下fetch。先不考虑跨域请求的使用方法,我们先请求同域的资源。例如:
fetch("http://blog.csdn.net/xiangzhihong8").then(function(response){console.log(response)})
fetch语法
使用 fetch 的构造函数请求数据后,返回一个 Promise 对象,然后根据具体的实际情况处理。
fetch("http://baidu.com")
.then(function(response){
// ...
})
说明,在请求后的 Response 中,常常有如下返回情况:
- Response.status 也就是 StatusCode,如成功就是 200 ;
- Response.statusText 是 StatusCode 的描述文本,如成功就是 OK ;
- Response.ok 一个 Boolean 类型的值,判断是否正常返回,也就是 StatusCode 为 200-299 。
fetch请求实例
1.使用get方式进行网络请求,例如:
fetch('http://nero-zou.com/test', {
method: 'GET'
}).then(function(response) {
//获取数据,数据处理
}).catch(function(err) {
//错误处理
});
2.使用post方式进行网络请求,例如:
let param = {user:'xxx',phone:'xxxxxx'};
fetch(url, {
method: 'post',
body: JSON.stringify(param)
}).then(function(response) {
//获取数据,数据处理
});
3.其它写法,例如:
try {
fetch(url, {
method: 'post',
body: JSON.stringify(param)
}).then(function(response) {
//获取数据,数据处理
});
} catch(e) {
//捕获异常消息
}
4.带header 或其它参数,例如:
fetch(url, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
})
})
fetch二次封装
function fetchPost(url ,data) {
let host = DIX.HOST + url;
let token = UTIL.getToken();
let dataUrl = '';
if (data) {
for (let item in data) {
if (data.hasOwnProperty(item)) {
dataUrl += ('&' + item + '=' + data[item]);
}
}
}
let body = 'client=1&version=3&token=' + token + dataUrl;
return fetch (host, {
method: 'POST',
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: body
}).then(function(res) {
if (res.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' + res.status);
return;
}
// 处理响应中的文本信息
return res.json();
}).catch(function(err) {
console.log('Fetch Error : %S', err);
})
}
fetch请求并填充界面
我们先看看使用fetch并填充界面后的完整效果。
要实现上面的效果,我们需要对数据进行监听,也就是所谓的状态机机制。
state: {
discounts: Array<Object>,
dataSource: ListView.DataSource
}
然后我们使用fetch进行网络请求,当有数据返回时,我们更改数据源的数据。
requestDiscount() {
fetch(api.discount)
.then((response) => response.json())
.then((json) => {
console.log(JSON.stringify(json));
this.setState({ discounts: json.data })
})
.catch((error) => {
alert(error)
})
}
那么什么时候出发这个请求呢?当我们界面挂载的时候就触发这个请求,所以我们在componentDidMount调用这个请求。
componentDidMount() {
this.requestDiscount();
}
返回的内容如下:
{
stid: "836121754643660800",
data: [
{
typeface_color: "#ff9900",
position: 0,
module: false,
maintitle: "今日爆款",
type: 1,
deputytitle: "5折来按摩",
solds: 0,
id: 19995,
share: {
message: "养生名店1折起,最高立减30元,",
url: "https://g.meituan.com/app/gfe-app-page-discount/index-mt.html"
},
title: "今日爆款",
deputy_typeface_color: "#21c0ae",
tplurl: "imeituan://www.meituan.com/web?url=https://g.meituan.com/app/gfe-app-page-discount/index-mt.html",
imageurl: "http://p0.meituan.net/w.h/feop/0044b4cebe650ada958da3458f51eae833656.png"
},
{
typeface_color: "#f6687d",
position: 0,
module: false,
maintitle: "电影特惠",
type: 1,
deputytitle: "神奇女侠",
solds: 0,
id: 19749,
share: {
message: "热门大片特惠,福利再来一波>>",
url: "http://i.meituan.com/firework/km1495594906"
},
title: "电影特惠",
deputy_typeface_color: "#c280fc",
tplurl: "imeituan://www.meituan.com/web?url=http://i.meituan.com/firework/km1495594906",
imageurl: "http://p1.meituan.net/w.h/feop/6d7deddaeecd3b6c1181902616f2b4c028136.png"
},
{
typeface_color: "#6bbd00",
position: 0,
module: false,
maintitle: "特价出游",
type: 1,
deputytitle: "泰国跟团清仓",
solds: 0,
id: 20001,
share: {
message: "特价出游,泰国跟团清仓",
url: "http%3a%2f%2fi.meituan.com%2ffirework%2fislandseasonMT"
},
title: "特价出游",
deputy_typeface_color: "#fc6a56",
tplurl: "imeituan://www.meituan.com/web?url=http%3a%2f%2fi.meituan.com%2ffirework%2fislandseasonMT",
imageurl: "http://p1.meituan.net/w.h/feop/80fe92619a56f760e06e8c84657acb9720105.png"
},
{
typeface_color: "#06c1ae",
position: 0,
module: false,
maintitle: "今日推荐",
type: 1,
deputytitle: "品质生活指南",
solds: 0,
id: 3283,
share: {
message: "吃喝玩乐全都有,尽在美团网!",
url: "http://api.mobile.meituan.com/group/v1/re/p"
},
title: "今日推荐",
deputy_typeface_color: "#fdb32b",
tplurl: "imeituan://www.meituan.com/recommend?url=http://api.mobile.meituan.com/group/v1/re/p",
imageurl: "http://p0.meituan.net/w.h/feop/24ab8d4d0c2bd36bb4b95d2a8c0b105236553.png"
}
],
server: {
time: 1496411274
},
paging: {
count: 4
}
}
到此,数据请求基本完成了,接下来就是怎么将数据绘制到界面上的问题。为了方便我们需要自定义一个GridView用来绘制这个九宫格界面。我们在render()中定义一个props来接受请求返回的数据。代码如下:
class GridView extends Component {
static defaultProps = {
infos: []
}
render() {
let { infos } = this.props
let gridItems = []
for (let i = 0; i < infos.length; i++) {
let gridItem = (
<GridItem info={infos[i]} key={i} onPress={() => this.props.onGridSelected(i)}/>
)
gridItems.push(gridItem)
}
return (
<View style={styles.container}>
{gridItems}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'space-between',
borderTopWidth: 1,
borderLeftWidth: 1,
borderColor: '#e9e9e9'
},
});
export default GridView;
然后我们在绘制每一个GridItem,这个有点类似于Android的Adapter或者ios的CollectionViewCell。代码如下,不做详细的介绍:
var Dimensions = require('Dimensions');
var screen = Dimensions.get('window');
class GridItem extends Component {
render() {
let info = this.props.info
let title = info.maintitle
let color = info.typeface_color
let subtitle = info.deputytitle
let imageUrl = info.imageurl.replace('w.h', '120.0').replace('http','https')
return (
<TouchableOpacity style={styles.container} onPress={this.props.onPress}>
<View>
<Heading1 style={{ color: color, marginBottom: 10}}>{title}</Heading1>
<Heading2 >{subtitle}</Heading2>
</View>
<Image style={styles.icon} source={{ uri: imageUrl}} />
</TouchableOpacity>
);
}
}
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
width: screen.width / 2 - 1,
height: screen.width / 4,
backgroundColor: 'white',
borderBottomWidth: 1,
borderRightWidth: 1,
borderColor: '#e9e9e9'
},
icon: {
width: screen.width / 5,
height: screen.width / 5,
}
});
export default GridItem;
到此我们就完成了fetch请求并绘制界面的功能。 附:本文源码 fetch请求二次封装
- 3299: [USACO2011 Open]Corn Maze玉米迷宫
- 2272: [Usaco2011 Feb]Cowlphabet 奶牛文字
- 1632: [Usaco2007 Feb]Lilypad Pond
- 1630/2023: [Usaco2005 Nov]Ant Counting 数蚂蚁
- Java设计模式(七)Decorate装饰器模式
- 1623: [Usaco2008 Open]Cow Cars 奶牛飞车
- 1622: [Usaco2008 Open]Word Power 名字的能量
- 3297: [USACO2011 Open]forgot
- 1740: [Usaco2005 mar]Yogurt factory 奶酪工厂
- 1741: [Usaco2005 nov]Asteroids 穿越小行星群
- 3298: [USACO 2011Open]cow checkers
- 3433: [Usaco2014 Jan]Recording the Moolympics
- 3410: [Usaco2009 Dec]Selfish Grazing 自私的食草者
- 3391: [Usaco2004 Dec]Tree Cutting网络破坏
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 视频上云/网络穿透/网络映射服务EasyNTS前端组织添加页面出现Vue冲突怎么解决?
- Pinpoint 一款强大的APM工具
- 1. Pandas系列 - 基本数据结构
- 6 年前,只会 JSP 和 Servlet 就可以找到工作
- Python文件处理实用指南
- 2. Pandas系列 - Series基本功能
- 1.3 广告算法专题 - 交叉验证
- 最好用的内网穿透工具合集
- JVM垃圾回收之垃圾回收器,程序员必须掌握的知识
- 5分钟Flink - 时间与语义案例详解
- 5分钟Flink - 时间语义和Watermark
- 3. Pandas系列 - DataFrame操作
- 4. Pandas系列 - 基本功能和统计操作
- 面经手册 · 第8篇《LinkedList插入速度比ArrayList快?你确定吗?》
- 无所不能的Embedding 2. FastText词向量&文本分类