javascript – 如何在React Native中为API请求创建进度条?

前端之家收集整理的这篇文章主要介绍了javascript – 如何在React Native中为API请求创建进度条?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
当我的程序获取天气数据时,我正在尝试制作一个简单的进度计数器,从0%到100%. API请求由index.ios.js中的getLocation()生成,该函数调用weatherApi.js中的fetchWeather().有没有办法衡量fetch函数对我的API请求的进度?如果没有,实施加载栏的好方法是什么?

weatherAPI.js

const rootUrl ='http://api.openweathermap.org/data/2.5/weather?appid=fcea54d0ceade8f08ab838e55bc3f3c0'

export const fetchWeather = (lat,lon) => {

    const url = rootUrl+'&lat='+lat+'&lon='+lon+"&units=metric"
    console.log(url)

  return fetch(url)
    .then(res => res.json())
    .then(json => ({
        temp: json.main.temp,weather: json.weather[0].main
    }))

}

index.ios.js

import React,{Component} from 'react';
import {
    AppRegistry,StyleSheet,Text,View,StatusBar
    } from 'react-native'

import Icon from 'react-native-vector-icons/Ionicons'
import {fetchWeather} from './weatherAPI'
import Highlight from 'react-native-highlight-words'

const iconNames = {
    Default: 'md-time',Clear: 'md-sunny',Rain: 'md-rainy',Thunderstorm: 'md-thunderstorm',Clouds: 'md-cloudy',Snow: 'md-snow',Drizzle: 'md-umbrella',}

const phrases = {

    Default:{
        title: "Fetchin the Weather",subtitle: "Be patient,you're witnessing a miracle",highlight: ["Fetchin"],color: "#636363",background: "#9C9C9C"
    },Clear: {
        title: "CLEAR.",subtitle: "You Better Go Outside",highlight: ["CLEAR"],color:"#E32500",background: "#FFD017"
    },Rain: {
        title: "It's Raining",subtitle: "You guessed it",highlight: ["Raining"],color:"#004A96",background:"#2F343A"
    },Thunderstorm: {
        title: "Not Just Raining,It's Storming",subtitle: "Free shower",highlight: ["Storming"],color:"#FBFF46",background:"#020202"
    },Clouds: {
        title: "Clouds for Days",subtitle: "Cotton candy skies",highlight: ["Days"],color:"#0044FF",background: "#939393"

    },Snow: {
        title: "Oh Yeah Bud. It's Snowin'",subtitle: "Make a snow angel bud",highlight: ["Snowin'"],color:"#021D4C",background:"#15A678"

    },Drizzle: {
        title: "Just a Wee Ol' Drizzle Lads",highlight: ["Wee","Ol'"],color:"#dbdbdb",background:"#1FBB68"

    },}

class App extends Component {


  componentWillMount() {

    this.state = {

        temp: 0,weather: 'Default'
    }   

  }

  componentDidMount() {
    this.getLocation()
}

  getLocation() {
    navigator.geolocation.getCurrentPosition(
      posData => fetchWeather(posData.coords.latitude,posData.coords.longitude)
      .then(res => this.setState({
        temp:Math.round(res.temp),weather: res.weather
      })),error => alert(error),{timeout: 10000}
      )
  }


    render(){
        console.log(this.state.weather)
        return(
        <View style={[styles.container,{backgroundColor: phrases[this.state.weather].background}]}>
          <StatusBar hidden={true}/>
            <View style={styles.header}>
            <Icon name={iconNames[this.state.weather]} size={80} color={'white'}/>
            <Text style={styles.temp}>{this.state.temp}°</Text>
            </View>
            <View style={styles.body}>
            <Highlight 
              style={styles.title}
              highlightStyle={{color: phrases[this.state.weather].color}}
              searchWords={phrases[this.state.weather].highlight}
              textToHighlight={phrases[this.state.weather].title}
              />
            <Text style={styles.subtitle}>{phrases[this.state.weather].subtitle}</Text>
            </View>
        </View>
        )
    }
}

const styles = StyleSheet.create({

    container: {
        flex:1,backgroundColor:'#FFD017'
    },header: {
        flexDirection:'row',alignItems:'center',justifyContent:'space-around',flex:1,},temp: {
        fontFamily: 'HelveticaNeue-Bold',fontSize: 45,color:'white'

    },body: {
        alignItems:'flex-start',justifyContent:'flex-end',flex:5,margin:10

    },title: {
        fontFamily: 'HelveticaNeue-Bold',fontSize: 90,color:'white',marginBottom:5

    },subtitle: {
        fontFamily: 'HelveticaNeue-Medium',fontSize: 16,color:'white'

    }



});

AppRegistry.registerComponent('IsItRaining',() => App)

解决方法

fetch API不包含 any progress callbacks,因此您的选项要么使用 XMLHttpRequest,这在React Native中完全支持,要么是一个本质上将在其上构建的库.例如,您可以修改fetchWeather函数来执行以下操作:
export const fetchWeather = (lat,lon,progress) => {
return new Promise((resolve,reject) => {
    const url = rootUrl+'&lat='+lat+'&lon='+lon+"&units=metric"
    console.log(url)
    var oReq = new XMLHttpRequest();

    oReq.addEventListener("progress",progress);
    oReq.open('GET',url);
    oReq.send();
    oReq.onreadystatechange = function() {
        if (oReq.readyState == XMLHttpRequest.DONE) {
            let data = JSON.parse(oReq.responseText);
            resolve({temp: data.main.temp,weather: json.weather[0].main});
        }
    }
});
}

进度是一个回调状态,您可以在其中更新状态.例如,在您的组件中,添加以下函数

function updateProgress (oEvent) {
  if (oEvent.lengthComputable) {
    var progress = oEvent.loaded / oEvent.total;
    this.setState({progress})
  } else {
    // Unable to compute progress information since the total size is unknown
  }
}

然后,呼叫变为:

fetchWeather(posData.coords.latitude,posData.coords.longitude,this.updateProgress.bind(this)) fetchWeather(posData.coords.latitude,posData.coords.longitude)

该示例改编自MDN.

猜你在找的JavaScript相关文章