React Native之Fetch簡單封裝、獲取網絡狀態


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上也不會出錯,但會有⚠️警告信息。

@react-native-community/netinfo傳送門>>>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM