1、Fetch的使用
fetch的使用非常簡單,只需傳入請求的url
fetch('https://facebook.github.io/react-native/movies.json');
當然是否請求成功與數據的處理,我們還需處理成功與失敗的回調
function getMoviesFromApiAsync() { return fetch('https://facebook.github.io/react-native/movies.json') .then((response) => response.json()) .then((responseJson) => { return responseJson.movies; }) .catch((error) => { console.error(error); }); }
通過response.json()將請求的返回數據轉化成json數據以便使用。通過.then
來對數據進行轉化處理或最終暴露給調用者;.catch
對異常的處理。
2、Fetch的簡單封裝
廢話少說,直接上代碼;
(1)封裝工具
代碼如下:
//一個 Promise 就是一個代表了異步操作最終完成或者失敗的對象 export default class HttpUtils{ static get=(url)=>{ return new Promise(((resolve, reject) => {//resolve 和 reject 函數被調用時,分別將promise的狀態改為fulfilled(完成)或rejected(失敗) fetch(url)//默認是GET .then(response=>response.json())//把數據解析成json格式,然后取出 .then(result=>{ resolve(result);//表示完成 }) .catch(error=>{ reject(error);//表示失敗 }) }) ) }; static post=(url,data)=>{ return new Promise(((resolve, reject) => { fetch(url,{ method:'POST', header:{ 'Accept':'application/json',//告訴服務器,我們能接受json格式的返回類型, 'Content-Type':'application/json',//告訴服務器,我們提交的數據類型 }, body:JSON.stringify(data),//(把你想提交得數據序列化為json字符串類型,然后提交)body中的數據就是我們需要向服務器提交的數據,比如用戶名,密碼等 })//返回 服務器處理的結果 .then(response=>response.json()) .then(result=>{ resolve(result); }) .catch(error=> { reject(error); }) }) ) } } //數據轉換成字符串 JSON.stringify(params) //將數據JSON化 JSON.parse(responseJSON)
(2)封裝工具的使用
1、首先引入頭文件
import HttpUtils from './HttpUtils';
2、實現對應的請求方法
//get數據 onLoad=(url)=>{ HttpUtils.get(url)//調用自定義組件方法,返回一個Promise .then(result=>{//then函數會返回一個新的promise this.setState({ result:JSON.stringify(result),//序列化:轉換為一個 (字符串)JSON字符串 }); console.log(result) }) .catch(error=> { this.setState({ result: JSON.stringify(error),//把錯誤信息格式化為字符串 }); console.log(result); }) }; //模擬登陸Post onSubmit=(url,data)=>{ HttpUtils.post(url,data) .then(result=>{ this.setState({ result:JSON.stringify(result),//序列化:轉換為一個 (字符串)JSON字符串 }); console.log(result); }) .catch(error=> { this.setState({ result: JSON.stringify(error),//把錯誤信息格式化為字符串 }); console.log(result); }) };
3、在需要使用的地方,發起請求;
<TouchableOpacity style={{marginVertical: 20 }} onPress={() => this.onLoad('https://******/submit_ajax.ashx?action=APP_GetLines')}> <Text>發送Get網絡請求</Text> </TouchableOpacity> <TouchableOpacity style={{marginVertical: 20 }} onPress={() => this.onSubmit('https://******/submit_ajax.ashx?action=APP_GetCardslist',{Uid:'37985'})}> <Text>發送POST網絡請求</Text> </TouchableOpacity>
更多內容,請參考:React Native網絡請求傳送門>>>
3、獲取網絡狀態
/** * Sample React Native App * https://github.com/facebook/react-native * @flow */ import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Text, NetInfo, ToastAndroid, View } from 'react-native'; class NetworkInfo extends Component { constructor(props) { super(props); this.state = { isConnected: null, connectionInfo: null, }; } componentDidMount() { //網絡是否連接的監聽 NetInfo.isConnected.addEventListener( 'isConnected', this._handleConnectivityChange ); //網絡狀態變化的監聽 NetInfo.addEventListener( 'statusChange', this._handleNetStatusChange ); //檢測網絡是否連接 NetInfo.isConnected.fetch().done( (isConnected) => { this.setState({ isConnected: isConnected }); } ); //檢測網絡連接狀態 NetInfo.fetch().done( (connectionInfo) => { this.setState({ connectionInfo }); } ); } componentWillUnmount() { //卸載兩個監聽 NetInfo.isConnected.removeEventListener( 'isConnected', this._handleConnectivityChange ); NetInfo.removeEventListener( 'statusChange', this._handleNetStatusChange ); } _handleConnectivityChange = (isConnected) => { ToastAndroid.show((isConnected ? 'online' : 'offline'), ToastAndroid.SHORT); } _handleNetStatusChange = (status) => { ToastAndroid.show('當然網絡狀態:' + status, ToastAndroid.SHORT); } render(){ } }
這個組件已經在RN剛出來(倆平台同時支持)的時候就已經存在了,用法大家都已經很熟悉了,但是在0.48+版本中,出現了一些變化,前面的用法都會過期。
主要完善了兩個方面的問題
- 目前的NetInfo API是分平台的.在iOS和Android平台上返回完全不同的值.
- 目前的NetInfo API無法判定連接的手機網絡是 2g, 3g, 還是 4g.
貢獻者為了不造成breaking changes,所以直接新增新的api,將前面的api改為黃色警告
- `fetch`方法過時了,用`getConnection`替代 - `change`事件過時了,用`connectionchange`替代. - `fetch`/`change`過時了,用`getConnection`/`connectionchange`替代。返回的枚舉值也變了。具體查看下面的值
ConnectionType(設備的網絡類型):
跨平台:
- none
- 設備處於離線狀態。
- wifi
- 設備處於聯網狀態且通過wifi鏈接,或者是一個iOS的模擬器。
- cellular
- 設備是通過Edge、3G、WiMax或是LTE網絡聯網的。
- unknown
- 發生錯誤,網絡狀況不可知
Android平台:
- bluetooth
- 藍牙數據連接
- ethernet
- 以太網數據連接
- wimax
- WiMAX數據連接
EffectiveConnectionType(無線網絡類型) :
- 2g
- 3g
- 4g
- unknown
具體用法,請參考:NetInfo傳送門>>>
4、@react-native-community/netinfo
第一步:安裝
yarn add @react-native-community/netinfo
或
npm install --save @react-native-community/netinfo
第二步:關聯項目
react-native link @react-native-community/netinfo
第三步:在項目中引用
import NetInfo from "@react-native-community/netinfo";
注意此處:使用過這個API之后,就不要再引用原有的NetInfo了,可能會引起沖突。如下:
import { NetInfo } from "react-native";
案例代碼。如下:
/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @format * @flow */ import React from 'react'; import {Text, View,TouchableWithoutFeedback} from 'react-native'; import NetInfo from '@react-native-community/netinfo'; export default class IsConnected extends React.Component<{}, $FlowFixMe> { state = { isConnected: null, // isConnectionExpensive: null, }; // _checkIfExpensive = () => { // NetInfo.isConnectionExpensive().then(isConnectionExpensive => { // this.setState({isConnectionExpensive}); // }); // }; componentDidMount() { NetInfo.isConnected.addEventListener( 'connectionChange', this._handleConnectivityChange, ); NetInfo.isConnected.fetch().done(isConnected => { this.setState({isConnected}); }); } componentWillUnmount() { NetInfo.isConnected.removeEventListener( 'connectionChange', this._handleConnectivityChange, ); } _handleConnectivityChange = isConnected => { this.setState({ isConnected, }); }; render() { return ( <View style={{backgroundColor:'white',marginTop:20,flex:1}}> <Text>{this.state.isConnected ? 'Online' : 'Offline'}</Text> {/* <TouchableWithoutFeedback onPress={this._checkIfExpensive}> <View> <Text> Click to see if connection is expensive: {this.state.isConnectionExpensive === true ? 'Expensive' : this.state.isConnectionExpensive === false ? 'Not expensive' : 'Unknown'} </Text> </View> </TouchableWithoutFeedback>*/} </View> ); } }
提示:代碼中注釋部分,是進行判斷是否是付費網絡,僅支持Android,但是在iOS上也不會出錯,但會有⚠️警告信息。