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

时间:2016-11-28 04:11:49

标签: javascript ios reactjs react-native fetch

当我的程序获取天气数据时,我正在尝试创建一个从0%到100%的简单进度计数器。 API请求由getLocation()index.ios.js内部fetchWeather()调用,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 })) } 内的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", subtitle: "Free shower", 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请求的进度?如果没有,实施加载栏的好方法是什么?

weatherAPI.js

spring.mongo.host=127.0.0.1
spring.mongo.port=27017
spring.mongo.databaseName=spring

index.ios.js

@Document (collection = "person")
public class Person {
    @Id
    String id;
    int age;
    String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

1 个答案:

答案 0 :(得分:8)

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