react-native官网Fetch介绍:https://facebook.github.io/react-native/docs/network.html#content
react-native中不支持$,也就是说我们无法使用$HTTP来调用API,根据react-native官网教程,我们可以使用fetch,这也是一个更好的网络API,它在react native中默认可以使用。
在react-native项目中,我们还是使用我们的惯用方法,写一个服务js来放我们的所有API,但是在react-native中,我们将会有一些定义上和使用方法上的变化。
了解fetch
fetch(input, init)
第一个参数input可以是一个字符串,包含获取资源的URL;
第二个参数对象是可选的,它可以自定义HTTP请求中的一些部分;
method
: 请求使用的方法,如 GET、
POST。
headers
: 请求的头信息,形式为 Headers
对象或 ByteString
。
body
: 请求的 body 信息:可能是一个 Blob
、BufferSource
、FormData
、URLSearchParams
或者 USVString
对象。注意 GET 或 HEAD 方法的请求不能包含 body 信息。
mode
: 请求的模式,如 cors、
no-cors 或者
same-origin。
credentials
: 请求的 credentials,如 omit、
same-origin 或者
include。
cache
: 请求的 cache 模式: default
, no-store
, reload
, no-cache
, force-cache
, or only-if-cached
.
fectch()的返回值是一个Promise对象,它可以使用then
和catch
指定回调函数:
fetch(input, init) .then((response) => response.json()) .then((responseJson) => {console.log(responseText);}) .catch((error) => {console.warn(error);});
fetch返回函数参数定义
fetch返回函数callback()的参数定义:
- 如果接口调用成功,我们返回callback(null,data);有两个参数:
第一个参数传null,代表接口调用成功;
第二个参数data为接口返回的数据; - 如果接口未调用成功,我们返回callback(err);只有一个参数:err为错误消息;
fetch示例
使用该方法时,不需要引入fetch,直接拿来用就可以了。
先来简述一下《意见反馈》demo都有哪些服务API功能:
- 根据app的GUID获得该app的信息(GET方法);
- 用户发送所填写的内容(POST方法)
app的界面实现过程就不呈现了,主要说明的是如何调用web API的。
首先来建一个服务:app-feedback-svc.js。代码如下:
var baseURL = "http://192.168.89.101:8082/api/", export default{ //获得某一app详细信息(不包含评论) getOneAppInfoDetail(appGUID, callback){ fetch(baseURL + 'api/app/app-info/' + appGUID, { method: 'GET' }).then((response) => response.json()) .then((responseJson) => { switch (responseJson.State) { case 0: var listOption = responseJson.Result.ListOption; var result = { tags: listOption.filter((item)=>item.OptionClass === 0).map((item)=>item.OptionString), expect: listOption.filter((item)=>item.OptionClass === 1).map((item)=>item.OptionString) }; callback(null, result); break; case 1: callback('参数无效'); break; case 2: callback('未知错误(异常)'); break; default: callback('其他错误'); break; } }) .catch((error) => { callback(error); }); }, //保存app评价 saveAppComment(AppGUID, IsLike, CommentDetail, WishFeature, PhoneType, Email, callback){ var wishItem = {}; WishFeature.filter((item)=>item.check == true).map((item, index)=>( wishItem['Item' + index] = item.label )); fetch(baseURL + 'api/comment/save-comment', { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ AppGUID: AppGUID, IsLike: IsLike, CommentDetail: CommentDetail, WishFeature: wishItem, PhoneType: PhoneType, Email: Email }) }).then((response) => response.json()) .then((responseJson) => { switch (responseJson.State) { case 0: callback(null); break; case 1: callback('参数无效'); break; case 2: callback('未知错误(异常)'); break; default: callback('其他错误'); break; } }) .catch((error) => { callback(error); }); } }
服务js承担中转作用,因此我们需要处理接口返回的数据的格式时,尽量在服务js中转换完成之后,再在页面中使用。
例如上述文件中, 获得app信息函数getOneAppInfoDetail(),接口返回的数据有所有的app信息,但是我们页面上不需要那么多信息,因此,我们需要在服务中,当接口调用成功并有数据返回后,我们要重新构造我们需要的数据格式:
//responseJson.State==0 var listOption = responseJson.Result.ListOption; var result = { tags: listOption.filter((item)=>item.OptionClass === 0).map((item)=>item.OptionString), expect: listOption.filter((item)=>item.OptionClass === 1).map((item)=>item.OptionString) }; callback(null, result); //这样返回的数据result就只含有我们所需要的数据了。
页面调用API时,根据定义的服务函数里的参数来进行传参来得到app的信息或者保存用户的反馈。
获得app信息:
使用的是fetch的GET方法,我们只需要一个参数(appGUID)即可得到app的信息。
根据服务中的返回函数callback()的定义,我们通过判断第一个参数是否为空来判断我们的接口是否调用成功,是否获得到我们的想要的数据。
import feedbackSvc from './services/app-feedback.js'; componentDidMount() { feedbackSvc.getOneAppInfoDetail(this.appGUID, function (info, data) { if (info == null) { var appDetailInfo = data; var list = appDetailInfo.expect.map((item)=>({check: false, label: item})); list.push({check: false, label: "其它功能"}); this.setState({appDetailInfo, list}); } else { alert(info); } }.bind(this)); }
保存反馈内容:
使用的是fetch的POST方法,我们需要把反馈的每一个内容都作为参数传给接口,并且这些参数的格式要同接口需要的参数一致才可以成功保存内容,当然像GET方法,接口返回的数据格式不一定是我们想要的,同样地,我们前台页面获得的数据格式不一定是接口所需要的格式,我们转换数据格式的代码也应该放在服务js中处理。如app-feedback-svc.js中的saveAppComment(),我们传过去的WishFeature是一个数组,但是接口需要的是一个对象,所以我们需要进行格式处理:
var wishItem = {}; WishFeature.filter((item)=>item.check == true).map((item, index)=>( wishItem['Item' + index] = item.label )); //这样我们得到的wishItem对象就是接口所需要的数据
页面中,当用户点击“发送”按钮后,用户所填写的数据才传到接口保存下来,所以我们需要定义一个函数_saveComment(),当用户点击时调用该函数,将所有内容都作为参数传给接口,如果调用接口成功,用户填写的数据将保存在我们的管理后台了。
import feedbackSvc from './services/app-feedback.js'; _saveComment() { feedbackSvc.saveAppComment(this.appGUID, this.state.isLike, this.state.appOption, this.state.list, phoneType, this.state.email, function (info, data) { if (info == null) { alert('感谢您的反馈!'); } else { alert(info); } }.bind(this)) }