Nizam  Mamedov
Nizam Mamedov

Reputation: 23

How to render a loader until data is fetched from server in React Native

I am fetching data from my server but is loading without indicator how I can add an indicator to my code? I want show loading indicator before fetching from server. Unfortunately, I'm not sure how to create a loader to wait for the data to load. Here is my currently code.

Here is my code

import { SectionList, Alert, ActivityIndicator } from 'react-native'
import Icon from 'react-native-vector-icons/Ionicons';
import styled from 'styled-components/native';
import Swipeable from 'react-native-swipeable-row';
import axios from "axios";

import { Appointment, SectionTitle } from '../components';



const HomeScreen = ({ navigation }) => {
  const [data, setData] = useState(null);
  const [isLoading, setIsLoading] = useState(false);

  const fetchAppointments = () => {
    setIsLoading(true);
    axios.get('https:*********')

    .then(({ data }) => {
      setData(data.data);
      setIsLoading(false);
    });
  }

  useEffect(fetchAppointments, []);
  useEffect(fetchAppointments, [navigation.state.params]);

  return (
    <Container>
     {data && ( <SectionList
          sections={data}
          keyExtractor={item => item._id}
          onRefresh={fetchAppointments}
          refreshing={isLoading}
          renderItem={({ item }) => (
            <Swipeable
              rightButtons={[
                <SwipeViewButton style={{ backgroundColor: '#B4C1CB' }}>
                  <Icon name="md-create" size={28} color="white" />
                </SwipeViewButton>,
                <SwipeViewButton
                  onPress={removeAppointment.bind(this, item._id)}
                  style={{ backgroundColor: '#F85A5A' }}
                >
                  <Icon name="ios-close" size={48} color="white" />
                </SwipeViewButton>
              ]}
            >
                <Appointment navigate={navigation.navigate} item={item} />
            </Swipeable>

        )}
        renderSectionHeader={({ section: { title } }) => (
          <SectionTitle>{title}</SectionTitle>
        )}
        />)}
    </Container>
)};

Upvotes: 0

Views: 1655

Answers (3)

Jagnesh Chawla
Jagnesh Chawla

Reputation: 892

React 16.6 added a component that lets you “wait” for some code to load and declaratively specify a loading state (like a spinner) while we’re waiting:

const ProfilePage = React.lazy(() => import('./ProfilePage')); // Lazy-loaded

// Show a spinner while the profile is loading
<Suspense fallback={<Spinner />}>
  <ProfilePage />
</Suspense>

Documentation

Upvotes: 0

Guilherme Ramalho
Guilherme Ramalho

Reputation: 186

You could do this

import { SectionList, Alert, ActivityIndicator } from 'react-native'
import Icon from 'react-native-vector-icons/Ionicons';
import styled from 'styled-components/native';
import Swipeable from 'react-native-swipeable-row';
import axios from "axios";
import ActivityIndicator from 'react-native';

import { Appointment, SectionTitle } from '../components';

const HomeScreen = ({ navigation }) => {
  const [data, setData] = useState(null);
  const [isLoading, setIsLoading] = useState(false);

  const fetchAppointments = () => {
    setIsLoading(true);
    axios.get('https:*********')

    .then(({ data }) => {
      setData(data.data);
      setIsLoading(false);
    });
  }

  useEEffect(fetchAppointments, []);
  useEffect(fetchAppointments, [navigation.state.params]);

  return (
    <Container>
      {isLoading ? (
        <ActivityIndicator size="large" color="#0000ff" />
      ) : (
        <>
          {data && ( <SectionList
            sections={data}
            keyExtractor={item => item._id}
            onRefresh={fetchAppointments}
            refreshing={isLoading}
            renderItem={({ item }) => (
              <Swipeable
                rightButtons={[
                  <SwipeViewButton style={{ backgroundColor: '#B4C1CB' }}>
                    <Icon name="md-create" size={28} color="white" />
                  </SwipeViewButton>,
                  <SwipeViewButton
                    onPress={removeAppointment.bind(this, item._id)}
                    style={{ backgroundColor: '#F85A5A' }}
                  >
                    <Icon name="ios-close" size={48} color="white" />
                  </SwipeViewButton>
                ]}
              >
                  <Appointment navigate={navigation.navigate} item={item} />
              </Swipeable>

          )}
          renderSectionHeader={({ section: { title } }) => (
            <SectionTitle>{title}</SectionTitle>
          )}
          />)}
        </>
      )}
    </Container>
)};

Upvotes: 2

omer.ersoy
omer.ersoy

Reputation: 334

Create a functional component that returns some styled activity indicator. Something like this:

        <View style={{styles.yourIndicatorStyle}}> //give the position and opacity or whatev you want 
            <ActivityIndicator
                size={"large"}
                color={"green"}
                animating={true} />
        </View>

import it in your home screen an use it like:

<Container>
 {isLoading && <YourIndicatorComponent />}
  ...
</Container>

Upvotes: 1

Related Questions