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请求并填充界面

我们先看看使用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();
    }

请求的接口如下:
https://api.meituan.com/group/v1/deal/topic/discount/city/1?ci=1&client=iphone&movieBundleVersion=100&msid=48E2B810-805D-4821-9CDD-D5C9E01BC98A2015-06-17-14-50363&userid=10086&utm_campaign=AgroupBgroupD100Fab_chunceshishuju__a__a___b1junglehomepagecatesort__b__leftflow___ab_gxhceshi__nostrategy__leftflow___ab_gxhceshi0202__b__a___ab_pindaochangsha__a__leftflow___ab_xinkeceshi__b__leftflow___ab_gxtest__gd__leftflow___ab_gxh_82__nostrategy__leftflow___ab_pindaoshenyang__a__leftflow___i_group_5_2_deallist_poitype__d__d___ab_b_food_57_purepoilist_extinfo__a__a___ab_trip_yidizhoubianyou__b__leftflow___ab_i_group_5_3_poidetaildeallist__a__b___ab_waimaizhanshi__b__b1___a20141120nanning__m1__leftflow___ab_pindaoquxincelue__a__leftflow___ab_i_group_5_5_onsite__b__b___ab_i_group_5_6_searchkuang__a__leftflow&utm_content=4B8C0B46F5B0527D55EA292904FD7E12E48FB7BEA8DF50BFE7828AF7F20BB08D&utm_medium=iphone&utm_source=AppStore&utm_term=5.7&uuid=4B8C0B46F5B0527D55EA292904FD7E12E48FB7BEA8DF50BFE7828AF7F20BB08D&version_name=5.7

返回的内容如下:

{
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请求二次封装

目录
相关文章
|
1月前
|
开发框架 前端开发 JavaScript
探索前端开发中的跨平台框架React Native
本文将介绍前端开发中一种备受关注的跨平台框架React Native,通过比较原生应用与React Native的优缺点,探讨其在实际项目中的应用以及未来发展趋势。
|
1月前
|
开发框架 前端开发 JavaScript
从零开始学习React Native开发
React Native是一种基于React框架的移动端开发框架,使用它可以快速地构建出高性能、原生的移动应用。本文将从零开始,介绍React Native的基础知识和开发流程,帮助读者快速入门React Native开发,并实现一个简单的ToDo应用程序。
|
11天前
|
存储 缓存 前端开发
react怎么只让接口请求一次
react怎么只让接口请求一次
15 0
|
1月前
|
开发框架 Dart 前端开发
【Flutter前端技术开发专栏】Flutter与React Native的对比与选择
【4月更文挑战第30天】对比 Flutter(Dart,强类型,Google支持,快速热重载,高性能渲染)与 React Native(JavaScript,庞大生态,热重载,依赖原生渲染),文章讨论了开发语言、生态系统、性能、开发体验、学习曲线、社区支持及项目选择因素。两者各有优势,选择取决于项目需求、团队技能和长期维护考虑。参考文献包括官方文档和性能比较文章。
【Flutter前端技术开发专栏】Flutter与React Native的对比与选择
|
2天前
|
前端开发 自动驾驶 程序员
鸿蒙? 车载?Flutter? React Native? 为什么我劝你三思,说点不一样的
本文探讨了在信息技术快速发展的背景下,开发者如何选择学习路径。作者提倡使用终局思维来规划职业发展,考虑技术的长远影响。终局思维注重长远目标、系统分析、反向规划和动态调整。以车载开发为例,预测未来智能汽车可能由语音助手主导,而非依赖平板界面。此外,作者建议不要过分投入打工状态,应思考创建自己的产品,如App,以实现技能补充和额外收入。选择对未来发展和自主性有益的技术,如Kotlin,比盲目追求热点更为重要。做减法和有标准的选择,能帮助减轻焦虑,实现更高效的成长。关注公众号“AntDream”获取更多相关内容。
9 1
|
4天前
|
开发框架 前端开发 JavaScript
移动应用开发中的跨平台策略:Flutter与React Native的比较
在移动应用领域,跨平台解决方案已成为开发者追求高效、成本效益和广泛覆盖的关键。本文深入探讨了两种领先的跨平台框架——Flutter和React Native,从技术架构、性能、社区生态及实际应用案例四个维度进行全面对比分析。通过这一比较,旨在为移动应用开发者提供选择合适框架的参考依据,帮助他们根据项目需求做出明智的决策。
|
13天前
|
前端开发 iOS开发 Android开发
React Native跨平台开发实战:从零到一
学习React Native跨平台开发,首先安装Node.js和React Native CLI,设置Android/iOS环境。使用CLI创建项目,如`npx react-native init MyProject`。运行应用:`npx react-native run-android`或`run-ios`。编写组件,如在App.js中创建Hello World。添加样式,安装第三方库如react-native-vector-icons,使用react-navigation进行路由和导航。
20 2
|
24天前
|
前端开发 JavaScript Android开发
使用React Native开发跨平台移动应用的技术详解
【5月更文挑战第22天】本文详述了使用React Native开发跨平台移动应用的技术,该框架由Facebook推出,基于JavaScript,支持iOS和Android。React Native通过JNI/JSI实现JavaScript到原生代码的转换,提供高效性能和原生体验。其优势包括跨平台性、原生体验、开发速度及社区支持。开发流程涉及环境搭建、项目创建、编码、调试与测试,以及构建与发布。注意事项包括性能优化、平台适配、利用第三方库和持续学习。React Native为开发者构建高质量跨平台应用提供了便捷途径,未来潜力无限。
|
28天前
|
缓存 前端开发 JavaScript
React和Next.js开发常见的HTTP请求方法
React和Next.js开发常见的HTTP请求方法
22 0
|
1月前
|
开发框架 移动开发 前端开发
【Uniapp 专栏】Uniapp 与 React Native 的对比分析
【5月更文挑战第14天】Uniapp和React Native是热门的跨平台移动开发框架。Uniapp以其一套代码多端运行、丰富的组件生态和较低的学习曲线受到青睐,适合快速开发简单应用。React Native基于React,拥有活跃社区和优秀性能,适合复杂应用。React Native在性能上略胜一筹,尤其在需要接近原生体验的场景。Uniapp的官方组件弥补了社区资源不足。选择时需考虑开发效率、性能需求、团队技术栈和社区支持。
【Uniapp 专栏】Uniapp 与 React Native 的对比分析