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)) }