React Native 开发豆瓣评分(四)集中管理 fetch 数据请求

豆瓣评分的API接口

接口是从网上查找的,看样子应该是微信小程序里面扣出来的(ua 里面有 wechatdevtools)

接口都需要设置apiKey(054022eaeae0b00e0fc068c0c0a2102a)和 ua(Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1 wechatdevtools/1.02.1902010 MicroMessenger/6.7.3 Language/zh_CN webview/ token/7858b5b98372a805690a212c8a57f80f),否则会返回错误

首页接口

个人中心接口

电影详情接口

封装 fetch 请求

使用 fetch 获取数据示例:

fetch('https://frodo.douban.com/api/v2/subject_collection/movie_showing/items?start=0&count=20&apiKey=054022eaeae0b00e0fc068c0c0a2102a', {
    method: 'GET',
    headers: {
        'Content-Type': 'application/json',
        'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1 wechatdevtools/1.02.1902010 MicroMessenger/6.7.3 Language/zh_CN webview/'
    }
}).then(response => {
    return response.json();
}).then(data => {
    console.log('获得数据:',data);
}).catch(error => {
    alert('error:' + JSON.stringify(error));
});

封装接口

在 src 目录创建 utils 目录,再在里面创建 ajax.js 统一管理应用的 fetch 请求,实现步骤如下:

1.先声明 url 和 apiKey 常量

const baseUrl = 'https://frodo.douban.com/api/v2';
const apiKey = '054022eaeae0b00e0fc068c0c0a2102a';

2.将 fetch 封装成xhr方法,方便使用是调用:

  • 参数为 pathname, method, params, headers
  • fetch 的 url 有 baseUrl + pathname 组成,但是实际从中可能有打点上报或其他三方接口,所以 pathname 如果含有 https 就不进行拼接
  • requestBody 中,headers 默认有 Content-Type 和 User-Agent,如果使用时还传入了 header 则继续添加传入的header
  • requestBody 的 body 必需是字符串,传入的 params 是 object 类型,需要将其 JSON.stringify
  • 如何请求为 get 请求,那么 requestBody 中就不能有 body,需要将参数拼接到 url 后面
  • 由于 get 接口有两种类型:https:xxx.com?xxx=xxx&xxx=xxx 和 https:xxx.com/id/xxx?xxx=xxx&xxx=xxx,第一种,直接 JSON.stringify(params) 拼接到 url 末尾,第二种,则 约定 id 为 $id,将 params 参数里面的 id 的值替换 $id。
const xhr = (pathname, method, params, headers) => {
    return new Promise((res, rej) => {
        let url = ~pathname.indexOf('https://') ? pathname : (baseUrl + pathname);
        //拼接
        let requestBody = {
            method: method,
            headers: {
                'Content-Type': 'application/json',
                'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1 wechatdevtools/1.02.1902010 MicroMessenger/6.7.3 Language/zh_CN webview/',
                ...headers
            },
            body: JSON.stringify(params)
        }

        if (method === 'GET' && params) {
            if (params.id && ~pathname.indexOf('$id')) {
                url = url.replace('$id', params.id);
                delete params.id;
            }

            let urlSearch = JSON.stringify(params).replace(/{|}|\"/ig, '').replace(/,/g, '&').replace(/:/g, '='); //将object转换成xxx=yyy&xxx=yyy这样的字符串
            url = urlSearch ? `${url}?${urlSearch}&apiKey=${apiKey}` : `${url}?apiKey=${apiKey}`;

            delete requestBody.body;
        }
        fetch(url, requestBody).then(response => {
            return response.json();
        }).then(data => {
            res(data);
        }).catch(error => {//暂时还不走到会出现哪些错误,暂时就先把错误弹出
            alert('error:' + JSON.stringify(error));
        });
    })
}

3.调用 xhr,导出 ajax 供其他模块使用,ajax 返回值是 xhr 返回的一个 Promise 对象

const ajax = (pathname, data, headers) => {
    return xhr(...apis[pathname], data, headers)
}

export default ajax;

调用时就非常方便了,也不用写 catch ,因为我们可以在 xhr 里面统一管理错误

ajax(pathname, data, headers).then(res => { xxxx });

4.处理 ...apis[pathname]

我们在 apis 里集中管理数据请求,get(pathname) 和 post(pathname) 方法需要返回 [pathname,method]

const apis = {
    showing: get('/subject_collection/movie_showing/items'),
    detail: get('/movie/$id'),
    login:post('https://accounts.douban.com/j/wxa/login/basic')
};

5.添加 get 和 post 方法

通过解构赋值的方式声明 get 与 post,如果后面还有其他类型的methods,如 put 之类的也可以继续在数组里面添加变量。

method 方法参数为 method,返回一个 function ,这个 function 参数为 pathname,最终就可以返回一个包含 pathname、method 的数组。

const method = method => pathname => [pathname, method];

const [get, post] = ['GET', 'POST'].map(value => method(value));

6.最终代码:

const baseUrl = 'https://frodo.douban.com/api/v2';
const apiKey = '054022eaeae0b00e0fc068c0c0a2102a';

const xhr = (pathname, method, params, headers) => {
    return new Promise((res, rej) => {
        let url = ~pathname.indexOf('https://') ? pathname : (baseUrl + pathname);
        let requestBody = {
            method: method,
            headers: {
                'Content-Type': 'application/json',
                'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1 wechatdevtools/1.02.1902010 MicroMessenger/6.7.3 Language/zh_CN webview/',
                ...headers
            },
            body: JSON.stringify(params)
        }

        if (method === 'GET' && params) {
            if (params.id && ~pathname.indexOf('$id')) {
                url = url.replace('$id', params.id);
                delete params.id;
            }

            let urlSearch = JSON.stringify(params).replace(/{|}|\"/ig, '').replace(/,/g, '&').replace(/:/g, '='); //将object转换成xxx=yyy&xxx=yyy这样的字符串
            url = urlSearch ? `${url}?${urlSearch}&apiKey=${apiKey}` : `${url}?apiKey=${apiKey}`;

            delete requestBody.body;
        }
        fetch(url, requestBody).then(response => {
            return response.json();
        }).then(data => {
            res(data);
        }).catch(error => {//暂时还不走到会出现哪些错误,暂时就先把错误弹出
            alert('error:' + JSON.stringify(error));
        });
    })
}

const method = method => pathname => [pathname, method];

const [get, post] = ['GET', 'POST'].map(value => method(value));

const apis = {
    //首页
    showing: get('/subject_collection/movie_showing/items'),
    hot: get('/subject_collection/movie_hot_gaia/items'),
    tv: get('/subject_collection/tv_hot/items'),
    variety: get('/subject_collection/tv_variety_show/items'),
    book: get('/subject_collection/book_bestseller/items'),
    music: get('/subject_collection/music_single/items'),
    //详情
    detail: get('/movie/$id'),
    photos: get('/movie/$id/photos')
};

const ajax = (pathname, data, headers) => {
    return xhr(...apis[pathname], data, headers)
}

export default ajax;

调用接口

import ajax from '../utils/ajax';

...
ajax('detail', {//获取详情
  id: 1291561
}).then(value => {
  console.log(value);
})
...
ajax('showing', {//获取热映列表
  start: 0,
  count: 20
}).then(value => {
  console.log(value);
})
...

原文地址:https://www.cnblogs.com/hl1223/p/11112673.html

时间: 2024-10-07 21:15:21

React Native 开发豆瓣评分(四)集中管理 fetch 数据请求的相关文章

React Native 开发豆瓣评分(一)环境搭建

详细可参考 官方文档,这里进记录一些重要过程. 安装环境 下载 Android Studio 选择 Custom 进行安装: Android SDK Android SDK Platform Performance (Intel ? HAXM) (AMD 处理器看这里) Android Virtual Device 安装各 SDK,推荐使用 choce 进行安装,非常简单: powershell -NoProfile -ExecutionPolicy Bypass -Command "iex (

React Native 开发豆瓣评分(五)添加字体图标

添加依赖 yarn add react-native-vector-icons Link 依赖 react-native link react-native-vector-icons 使用默认字体图标 import Icon from 'react-native-vector-icons/AntDesign'; //可以选择AntDesign.FontAwesome.EvilIcons... <Icon name="search1" size={30} color="#

react native 开发IOS

转载自kaich blog(http://www.kaich.xyz) 接触 react native 对于技术,我比较喜欢追新.看到报道大名鼎鼎的facebook(开源界的模范,发布了很多高质量的开源框架)开源了移动端跨平台的新框架react native,于是就迫不及待的开始接触它了.react native的目的是为了让前端开发任务能开发移动端(ios程序员相对于web端来说要少得多),于是就有了这样的框架.对于我们IOS程序员有没有必要去学它,看到它另外一个特性:跨平台,而且又一定程度的

【React Native开发】React Native开发IDE安装及配置

转载请标明出处: http://blog.csdn.net/developer_jiangqq/article/details/50476350 本文出自:[江清清的博客] (一)前言 上一讲我们已经对于在OS X系统上面对于React Native For Android的环境搭建以及第一个实例做了详细讲解.所谓工欲善其事,必先利其器,做React Native开发也和其他应用开发一样,最好有一个比较好的IDE工具.那么这边比较推荐以下几款工具:sublime,webstorm以及官网推荐的N

React Native开发入门

目录: 一.前言 二.什么是React Native 三.开发环境搭建 四.预备知识 五.最简单的React Native小程序 六.总结 七.参考资料 一.前言 虽然只是简单的了解了一下React的皮毛,但是对React Native的学习就轻松了好多.所以在学习React Native之前,最好还是先学习一下React.因为我学习的iOS开发,对iOS更加了解,所以里面主要涉及到的平台也是iOS. 二.什么是React Native React Native是一款用来开发真正原生.可渲染iO

Mac配置React Native开发环境

一直觉得学习一样东西,不动手怎么也学不会,就像学习swift,看了视频没有动手操作,记住的也就那么点,自己写出东西不是这里有问题就是那里出错. 所以,以后学习自己要多动手. 现在我的学习任务就是: 提高自己的iOS代码专业能力,掌握Swift3.0,顺便学习学习React Native. 学习一门语言当然少不了硬件和软件设备啦,不然怎么学习...嘿嘿,对吧!!!! 下面记录下自己配置React Native开发环境: 1> 安装brew: 打开终端,输入:   /usr/bin/ruby -e

React Native 开发之 (02) 用Sublime 3作为React Native的开发IDE

Sublime Text是一个代码编辑器.也是HTML和散文先进的文本编辑器.漂亮的用户界面和非凡的功能,例如:迷你地图,多选择Python插件,代码段等等.完全可自定义键绑定,菜单和工具栏等等.漂亮的用户界面和非凡的功能,Sublime Text的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等. 1.下载安装Sublime 3 Sublime 3的下载地址: http://www.sublimetext.com/3 选着相应的平

DECO 一个REACT NAtive 开发IDE工具

DECO 一个REACT NAtive 开发IDE工具. 目前只支持 OS,NO WINDOWS https://www.decosoftware.com/ 一个方便的快速 ERXPRESS 教程:http://www.reactnativeexpress.com/    配套学习.

React Native开发的通讯录应用

React Native开发的通讯录应用(使用JavaScript开发原生iOS应用,vczero) 0.前言: 项目地址:https://github.com/vczero/React-Native-App 欢迎大家提issues讨论任何问题,包括“试衣间”.... 一.项目介绍 基于React-Native & Node通讯录App (1)主要完成的功能有: 基于文件系统的Node.js服务端; 通讯录功能(分类页 + 列表页 + 拨号邮箱邮件) 公告功能(列表页 + 详情页) 通讯录和内容