How to show loading progress or spinner in the middle of the screen with React Native?

45,288

Solution 1

So in your case you can do several things

  1. You can use React Native Activity Indicator -> View
  2. You can use Overlay Library -> react-native-loading-spinner-overlay -> View GitHub
  3. If you like to make loading like facebook / instagram -> then use react-native-easy-content-loader -> View GitHub

Assume that you are using React Native Activity Indicator :

import { ActivityIndicator } from "react-native";

export default class HomeScreen extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isLoading: true
    };
  }

  //Get Home Screen Data API Action
  componentDidMount() {
    this.loadAPI(); // Call home screen get data API function
  }

  //Login API Function
  loadAPI = () => {
    this.setState({ isLoading: true }); // Once You Call the API Action loading will be true
    fetch(API_URL, {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      }
    })
      .then(response => response.json())
      .then(responseText => {
        // You can do anything accroding to your API response
        this.setState({ isLoading: false }); // After getting response make loading to false
      })
      .catch(error => {});
  };

  render() {
    return (
      <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
        {this.state.isLoading && <ActivityIndicator color={"#fff"} />}
      </View>
    );
  }
}
  • If you want to hide all the view until loading finish like images, so you can use custom library instead of Activity Indicator.

Solution 2

I have created my custom Loader component. Using this you can display built in ActivityIndicator or your custom gif loader image with overlay.

Loader.js

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

class Loader extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isLoading: this.props.isLoading
    }
  }

  static getDerivedStateFromProps(nextProps) {
    return {
      isLoading: nextProps.isLoading
    };
  }

  render() {
    return (
      <Modal
        transparent={true}
        animationType={'none'}
        visible={this.state.isLoading}
        style={{ zIndex: 1100 }}
        onRequestClose={() => { }}>
        <View style={styles.modalBackground}>
          <View style={styles.activityIndicatorWrapper}>
            <ActivityIndicator animating={this.state.isLoading} color="black" />
            
            {/* If you want to image set source here */}
            {/* <Image
              source={require('../assets/images/loader.gif')}
              style={{ height: 80, width: 80 }}
              resizeMode="contain"
              resizeMethod="resize"
            /> */}
          </View>
        </View>
      </Modal>
    )
  }
}

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

export default Loader

Now you can use it when you have to display loading indicator as below :

<Loader isLoading={this.state.isLoading} />

Solution 3

import { ActivityIndicator } from 'react-native';

export default class LoginScreen extends Component {
    constructor(props) {
        super(props);
        this.state = {
            spinner : true
        }
    }
    render() {
        return (
        <View style={{flex : 1, justifyContent: 'center', alignItems: 'center',}}>
        {
          this.state.spinner &&
          <ActivityIndicator  color={'#fff'} />
        }
        </View>
        )
    }
}

Solution 4

So you can show the SPinner for suppose when you have to load an API or something and when you get the response of api, you can set spinner loading value to false.

For eg :

import {View, ActivityIndicator } from 'react-native';

export default class MainScreen extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            spinner : true
        }
    }

componentDidMount(){
this.loadApi();
}

loadApi = async() => {
let result = axios.get('url').then((data) =>{
this.setState({spinner:false});
}
).catch((err) => this.setState({spinner:false})
}

    render() {
        return (
        <View style={{flex : 1, justifyContent: 'center', alignItems: 'center',}}>
        {
          this.state.spinner? <ActivityIndicator  color={'#fff'} />:<View><Text>Data loaded</Text></View>

        }
        </View>
        )
    }
}

Solution 5

you have to use ActivityIndicator you can have to load this activityindicator before getting data from the server , you have to check below code hope you will understand

    import React, {useEffect, useState} from 'react';
import {ActivityIndicator, View, Dimensions} from 'react-native';
import HomeScreen from './Home';

const DataViewer = () => {
  const [data, setData] = useState([]);
  const {height, width} = Dimensions.get('window');
  useEffect(() => {
    fetch('http://example.com/movies.json')
      .then(response => {
        return response.json();
      })
      .then(myJson => {
        setData(myJson);
      });
  });

  return data.length > 0 ? (
    <HomeScreen data={data} />
  ) : (
    <View
      style={{justifyContent: 'center', alignItems: 'center', height, width}}>
      <ActivityIndicator size="large" color="#0000ff" />
    </View>
  );
};

export default DataViewer;
Share:
45,288
Happy Smile
Author by

Happy Smile

Updated on July 09, 2022

Comments

  • Happy Smile
    Happy Smile almost 2 years

    I am developing React Native app.

    I was able to solve all problems by myself but this is exception. I am going to load another screen with bottom tab navigator.

    For example, after user login to the app, it should show main home screen which has many pictures and many style sheet effects, icons. Because of that, after login confirm ( I mean after alert of the login confirm), the main home screen appears after a few seconds.

    So I want to show some spinner in the login screen while loading main home screen in the background and when it is ready to show, erase spinner and show main home screen. How can I do this?

    My bottom tab navigator was simply created with createBottomTabNavigator() method.

  • Happy Smile
    Happy Smile over 4 years
    Thanks for your answer. But what I want to know is that how to set those this.state.spinner. When I have to set it true and when false?
  • Happy Smile
    Happy Smile over 4 years
    I get great help from you. I still have a question. Can you explain about navigation.dispatch?
  • Akila Devinda
    Akila Devinda over 4 years
    @Yuri Glad to help you ! You can see this thread about dispatch -> stackoverflow.com/questions/43869903/…
  • Akila Devinda
    Akila Devinda over 4 years