0
0
React Nativemobile~20 mins

Loading and error states in React Native - Mini App: Build & Ship

Choose your learning style9 modes available
Build: Data Fetch Screen
This screen fetches data from a fake API and shows loading and error states.
Target UI
-------------------------
| Data Fetch Screen      |
|-----------------------|
| [Loading spinner]      |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
-------------------------
Show a loading spinner while fetching data
Show fetched data as text when successful
Show an error message if fetching fails
Add a button to retry fetching data
Starter Code
React Native
import React, { useState, useEffect } from 'react';
import { View, Text, Button, ActivityIndicator, StyleSheet } from 'react-native';

export default function DataFetchScreen() {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [data, setData] = useState(null);

  // TODO: Add fetchData function here

  useEffect(() => {
    // TODO: Call fetchData when component mounts
  }, []);

  return (
    <View style={styles.container}>
      {/* TODO: Show loading spinner, data text, or error message here */}
      {/* TODO: Add retry button here */}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 16
  }
});
Task 1
Task 2
Task 3
Task 4
Task 5
Task 6
Solution
React Native
import React, { useState, useEffect } from 'react';
import { View, Text, Button, ActivityIndicator, StyleSheet } from 'react-native';

export default function DataFetchScreen() {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [data, setData] = useState(null);

  async function fetchData() {
    setLoading(true);
    setError(null);
    setData(null);
    try {
      const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
      if (!response.ok) throw new Error('Network response was not ok');
      const json = await response.json();
      setData(json);
    } catch (e) {
      setError('Failed to load data.');
    } finally {
      setLoading(false);
    }
  }

  useEffect(() => {
    fetchData();
  }, []);

  return (
    <View style={styles.container}>
      {loading && <ActivityIndicator size="large" color="#0000ff" accessibilityLabel="Loading indicator" />}
      {!loading && error && <Text accessibilityRole="alert" style={styles.errorText}>{error}</Text>}
      {!loading && data && <Text style={styles.dataText}>{data.title}</Text>}
      <Button title="Retry" onPress={fetchData} accessibilityLabel="Retry fetching data button" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 16
  },
  errorText: {
    color: 'red',
    marginBottom: 12,
    fontSize: 16
  },
  dataText: {
    fontSize: 18,
    marginBottom: 12
  }
});

This screen uses React Native hooks to manage loading, error, and data states.

The fetchData function is async. It sets loading to true and clears previous error and data. Then it fetches data from a fake API. If successful, it saves the data. If there is an error, it sets an error message. Finally, it sets loading to false.

The useEffect hook calls fetchData once when the screen loads.

The UI shows a spinner while loading, an error message if there was a problem, or the fetched data's title if successful. The Retry button lets the user try fetching again.

Accessibility labels and roles help screen readers understand the UI states.

Final Result
Completed Screen
-------------------------
| Data Fetch Screen      |
|-----------------------|
|       (spinner)        |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
| [Retry Button]         |
-------------------------
When the screen loads, a spinner appears while data loads.
If loading succeeds, the data title text appears.
If loading fails, an error message appears in red.
Pressing the Retry button tries to fetch data again.
Stretch Goal
Add pull-to-refresh functionality to reload data when the user swipes down.
💡 Hint
Use React Native's RefreshControl with a ScrollView or FlatList to implement pull-to-refresh.