0
0
React Nativemobile~20 mins

React Query for data fetching in React Native - Mini App: Build & Ship

Choose your learning style9 modes available
Build: User List Screen
This screen fetches and displays a list of users from a remote API using React Query. It shows loading and error states and allows refreshing the list.
Target UI
-------------------------
|      User List         |
|-----------------------|
| [Loading spinner...]   |
|                       |
|                       |
|                       |
|                       |
|                       |
|-----------------------|
| Refresh Button         |
-------------------------
Use React Query to fetch user data from https://jsonplaceholder.typicode.com/users
Show a loading indicator while fetching data
Display an error message if fetching fails
Render the list of user names in a scrollable list
Add a Refresh button to refetch the data on demand
Starter Code
React Native
import React from 'react';
import { View, Text, Button, FlatList, ActivityIndicator, StyleSheet } from 'react-native';
import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query';

const queryClient = new QueryClient();

function UserList() {
  // TODO: Use useQuery to fetch users

  return (
    <View style={styles.container}>
      {/* TODO: Show loading indicator */}
      {/* TODO: Show error message */}
      {/* TODO: Render FlatList of users */}
      {/* TODO: Add Refresh button */}
    </View>
  );
}

export default function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <UserList />
    </QueryClientProvider>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, padding: 16, backgroundColor: '#fff' },
  item: { padding: 12, borderBottomWidth: 1, borderBottomColor: '#ccc' },
  errorText: { color: 'red', marginBottom: 10 },
  loading: { marginVertical: 20 }
});
Task 1
Task 2
Task 3
Task 4
Task 5
Solution
React Native
import React from 'react';
import { View, Text, Button, FlatList, ActivityIndicator, StyleSheet } from 'react-native';
import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query';

const queryClient = new QueryClient();

function UserList() {
  const { data, error, isLoading, refetch } = useQuery(['users'], async () => {
    const response = await fetch('https://jsonplaceholder.typicode.com/users');
    if (!response.ok) throw new Error('Network response was not ok');
    return response.json();
  });

  if (isLoading) {
    return <ActivityIndicator size="large" style={styles.loading} accessibilityLabel="Loading users" />;
  }

  if (error) {
    return (
      <View style={styles.container}>
        <Text style={styles.errorText} accessibilityRole="alert">Error loading users: {error.message}</Text>
        <Button title="Retry" onPress={refetch} accessibilityLabel="Retry fetching users" />
      </View>
    );
  }

  return (
    <View style={styles.container}>
      <FlatList
        data={data}
        keyExtractor={item => item.id.toString()}
        renderItem={({ item }) => <Text style={styles.item}>{item.name}</Text>}
        accessibilityLabel="User list"
      />
      <Button title="Refresh" onPress={refetch} accessibilityLabel="Refresh user list" />
    </View>
  );
}

export default function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <UserList />
    </QueryClientProvider>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, padding: 16, backgroundColor: '#fff' },
  item: { padding: 12, borderBottomWidth: 1, borderBottomColor: '#ccc', fontSize: 16 },
  errorText: { color: 'red', marginBottom: 10, fontSize: 16 },
  loading: { flex: 1, justifyContent: 'center', alignItems: 'center' }
});

We use the useQuery hook from React Query to fetch the user data asynchronously. It manages loading, error, and data states for us.

While loading, we show an ActivityIndicator spinner. If an error happens, we display a red error message and a Retry button that calls refetch.

When data is loaded, we render a FlatList showing user names. The Refresh button also calls refetch to reload the data on demand.

This approach keeps the UI responsive and handles network states cleanly with minimal code.

Final Result
Completed Screen
-------------------------
|      User List         |
|-----------------------|
| Leanne Graham          |
| Ervin Howell           |
| Clementine Bauch       |
| Patricia Lebsack       |
| Chelsey Dietrich       |
| Mrs. Dennis Schulist   |
| Kurtis Weissnat        |
| Nicholas Runolfsdottir |
| Glenna Reichert        |
| Clementina DuBuque     |
|-----------------------|
| Refresh Button         |
-------------------------
When the screen loads, a spinner shows until users are fetched.
If fetching fails, an error message and Retry button appear.
User names appear in a scrollable list after loading.
Pressing Refresh button reloads the user list from the API.
Stretch Goal
Add pull-to-refresh functionality to reload the user list by pulling down on the list.
💡 Hint
Use FlatList's refreshing and onRefresh props with React Query's isFetching and refetch.