最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to render a loader until data is fetched in React Native - Stack Overflow

programmeradmin1浏览0评论

I am fetching data through an async request. I know that I need to wait for the api request to plete before displaying the data. Unfortunately, I'm not sure how to create a loader to wait for the data to load.I am new to react, so if I could also get help with implementing it as well, that would be fantastic! Here is my current code:

import React, { Component, PropTypes } from 'react';
import { View, Text, ListView, StyleSheet, TouchableHighlight} from 'react- native';
import Header from '../Components/Header';
import Api from '../Utility/Api';


export default class CalendarPage extends Component {

constructor(props) {
super(props);
}

async ponentWillMount() { this.setState(
    {data: await Api.getDates()},

    )
}

  render() {
    return (
      <View style={{flex: 1}}>
        <Header pageName="Calendar" navigator={this.props.navigator}/>
        <View style = {{flex:9}}>
            <View>
              { this.state.data.days[0].items.map((item) => (
                <View>
                  <Text>{item.summary}</Text>
                  <Text>{item.start.dateTime}</Text>
                  <Text>{item.description}</Text>
                </View>
              ))}
            </View>
         </View>
      </View>
    );
  }

}

I am fetching data through an async request. I know that I need to wait for the api request to plete before displaying the data. Unfortunately, I'm not sure how to create a loader to wait for the data to load.I am new to react, so if I could also get help with implementing it as well, that would be fantastic! Here is my current code:

import React, { Component, PropTypes } from 'react';
import { View, Text, ListView, StyleSheet, TouchableHighlight} from 'react- native';
import Header from '../Components/Header';
import Api from '../Utility/Api';


export default class CalendarPage extends Component {

constructor(props) {
super(props);
}

async ponentWillMount() { this.setState(
    {data: await Api.getDates()},

    )
}

  render() {
    return (
      <View style={{flex: 1}}>
        <Header pageName="Calendar" navigator={this.props.navigator}/>
        <View style = {{flex:9}}>
            <View>
              { this.state.data.days[0].items.map((item) => (
                <View>
                  <Text>{item.summary}</Text>
                  <Text>{item.start.dateTime}</Text>
                  <Text>{item.description}</Text>
                </View>
              ))}
            </View>
         </View>
      </View>
    );
  }

}

Share Improve this question asked Mar 17, 2017 at 0:42 JerryVonJinglesJerryVonJingles 572 gold badges2 silver badges7 bronze badges 1
  • I think you can do two returns so if there is no state, then return a loader otherwise return the data loader. And I don't think you've set up your initial state yet. – A. L Commented Mar 17, 2017 at 0:54
Add a ment  | 

2 Answers 2

Reset to default 11

A simple example using ActivityIndicator -

import ActivityIndicator

import { View, Text, ListView, StyleSheet, TouchableHighlight, ActivityIndicator} from 'react- native';

set data state to null

  constructor(props) {
    super(props);
    this.state = {
      data: null
    }
  }

do conditional rendering

  render() {
    if (!this.state.data) {
      return (
        <ActivityIndicator
          animating={true}
          style={styles.indicator}
          size="large"
        />
      );
    }

    return (
      <View style={{flex: 1}}>
        <Header pageName="Calendar" navigator={this.props.navigator}/>
        ....
        ....
      </View>
    );
  }
}

indicator style

const styles = StyleSheet.create({
  indicator: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    height: 80
  }
});

Although solution proposed by @vinayr works fine but user will still be able to click on screen and perform some action even while loader is being shown which can lead to crash.

One solution is wrap loader inside a Modal.

import React, { Component } from 'react';
import {
  StyleSheet,
  View,
  Modal,
  ActivityIndicator,
} from 'react-native';

const styles = StyleSheet.create({
  modalBackground: {
    flex: 1,
    alignItems: 'center',
    flexDirection: 'column',
    justifyContent: 'space-around',
    backgroundColor: '#00000040',
  },
  activityIndicatorHolder: {
    backgroundColor: '#FFFFFF',
    height: 100,
    width: 100,
    borderRadius: 10,
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'space-around',
  },
});


const SmartLoader = (props) => {
  const {
    isLoading,
    ...attributes
  } = props;

  return (
    <Modal
      transparent
      animationType={'none'}
      visible={isLoading}
      onRequestClose={() => { console.log('Noop'); }}
    >
      <View style={styles.modalBackground}>
        <View style={styles.activityIndicatorHolder}>
          <ActivityIndicator
            animating={isLoading}
            size="large"
          />
        </View>
      </View>
    </Modal>
  );
};

export default SmartLoader;

After that you can use it anywhere in your ponent, user will not be able to perform any action till loader is finished ( made hidden based on flag)

发布评论

评论列表(0)

  1. 暂无评论