• 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传送门>>>

  • 相关阅读:
    【设计模式(17)】行为型模式之中介者模式
    服务器迁移--MySQL数据库迁移
    巧妙解决element-ui下拉框选项过多的问题
    关于后台返回的文件流下载方法
    关于input框只让输入数字的写法
    关于element ui 全局配置某些组件的属性方法
    关于echarts的南丁格尔玫瑰图 极值导致展示效果不好的解决方案
    mock数据的使用方法
    配置 git账号和邮箱
    vite 发布了正式版版了 用起来
  • 原文地址:https://www.cnblogs.com/xjf125/p/10451889.html
Copyright © 2020-2023  润新知