1500+ ready React Native mobile app screens

Affiliates
Blog

How do I implement a loading spinner while fetching data in React Native?

Vibrant abstract flower design in warm tones with a yellow background, showcasing digital art creativity.
Photo by Marek Piwnicki on Pexels

To implement a loading spinner in React Native while fetching data, you can use the ActivityIndicator component. Set a loading state to true before your data fetch begins, and switch it to false once your data is loaded to toggle the spinner's visibility.

How do I use the ActivityIndicator component?

You can use the ActivityIndicator component from React Native. It provides a simple spinner that can be styled with props like size and color. Here's how to implement it:

import React, { useState, useEffect } from 'react';
import { View, ActivityIndicator, FlatList, Text } from 'react-native';

const MyComponent = () => {
    const [loading, setLoading] = useState(true);
    const [data, setData] = useState([]);

    useEffect(() => {
        const fetchData = async () => {
            // Start fetching data
            setLoading(true);
            const response = await fetch('https://jsonplaceholder.typicode.com/posts');
            const result = await response.json();
            setData(result);
            // Data fetching complete
            setLoading(false);
        };
        fetchData();
    }, []);

    return (
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
            {loading ? <ActivityIndicator size="large" color="#0000ff" /> : 
            <FlatList
                data={data}
                keyExtractor={(item) => item.id.toString()}
                renderItem={({ item }) => <Text>{item.title}</Text>}
            />}
        </View>
    );
};

export default MyComponent;

How do I change the size and color of the spinner?

You can customize the ActivityIndicator by changing its size and color properties. For example:

<ActivityIndicator size="small" color="green" />

Available sizes are small and large, or you can provide a numerical value for custom sizes. Be mindful that large spinners can impact performance on mid-range Android devices.

How do I handle loading state correctly?

Setting up your loading state correctly prevents displaying the spinner unnecessarily. Ensure the spinner only appears:

  1. When starting data fetching by setting setLoading(true) before your async call.
  2. When the data has finished loading by switching setLoading(false) after you process your data.

Example with conditional rendering:

The loading state is toggled to show the spinner:

return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        {loading ? <ActivityIndicator size="large" color="#0000ff" /> : <MyDataDisplayComponent data={data} />}
    </View>
);

What should I do if my app is laggy while fetching data?

If your React Native app is lagging on data fetch, consider the following optimizations:

  • Utilize useMemo or useCallback: Memoize expensive calculations or functions that are called on re-renders.
  • Lazy loading: Load data incrementally instead of all at once.
  • Optimize FlatList: Use the FlatList props initialNumToRender and windowSize to minimize UI jank.
  • Test on actual devices: Ensure that your app performs well on lower-end devices.

How do I implement a timeout for the loading spinner?

You can implement a timeout for your loading spinner using a setTimeout. This will allow you to potentially handle long loading times:

useEffect(() => {
    const timer = setTimeout(() => {
        if (loading) {
            setLoading(false);
            alert('Data is taking too long to load.');
        }
    }, 10000); // 10 seconds
    return () => clearTimeout(timer);
}, [loading]);

Be cautious about using alert dialogs in production environments because they can disrupt user experience. Instead, consider displaying a user-friendly notification.

How do I implement a skeleton loader as an alternative?

If you want a smoother user experience, use a skeleton loader instead of a spinner. Libraries like react-native-skeleton-placeholder can help you create skeleton loading states.

Install it via npm:

npm install react-native-skeleton-placeholder

Here’s a simple implementation:

import SkeletonPlaceholder from "react-native-skeleton-placeholder";

return (
    <View>
        {loading ? (
            <SkeletonPlaceholder>
                <SkeletonPlaceholder.Item>
                    <View style={{ width: 200, height: 20 }} />
                    <View style={{ width: 150, height: 20 }} />
                </SkeletonPlaceholder.Item>
            </SkeletonPlaceholder>
        ) : ( /* Your data rendering here */ )}
    </View>
);

Where can I find more resources for these implementations?

For more in-depth documentation, check out the official React Native documentation for the ActivityIndicator as well as the FlatList. These resources are great starting points for further learning.

Moving forward, implementing a loading spinner enhances user experience significantly during data fetch operations. Implement the examples above to get started immediately.