標籤:
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))}
React Native教程 - 調用Web API