Chapter 6: Working with APIs

Welcome back to our React Native journey. So far, we've built the basics and handled state, props, and navigation. Now, it’s time to add some real-world functionality by working with APIs. This chapter will guide you through fetching data from an API and displaying it in your app.

6.1 Setting Up

First, let’s set up a simple React Native project. If you haven’t already, create a new project:

npx react-native init ApiExample
cd ApiExample
npx react-native run-android # For Android
npx react-native run-ios # For iOS

Next, we need an API to fetch data from. For this example, we’ll use the JSONPlaceholder API, which provides a fake online REST API for testing and prototyping.

6.2 Fetching Data

Let's fetch a list of posts from JSONPlaceholder and display them in our app. Create a new file called App.js and add the following code:

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

const App = () => {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/posts')
      .then(response => response.json())
      .then(data => setPosts(data))
      .catch(error => console.error('Error fetching data:', error));
  }, []);

  return (
    <View style={styles.container}>
      <Text style={styles.header}>Posts</Text>
      <FlatList
        data={posts}
        keyExtractor={item => item.id.toString()}
        renderItem={({ item }) => (
          <View style={styles.post}>
            <Text style={styles.title}>{item.title}</Text>
            <Text>{item.body}</Text>
          </View>
        )}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingTop: 50,
    paddingHorizontal: 20,
  },
  header: {
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 20,
  },
  post: {
    marginBottom: 20,
    padding: 20,
    backgroundColor: '#f9f9f9',
    borderRadius: 5,
  },
  title: {
    fontSize: 18,
    fontWeight: 'bold',
  },
});

export default App;

Understanding the Code

  • useState: We use the useState hook to create a state variable posts to store our fetched data.

  • useEffect: The useEffect hook is used to fetch data when the component mounts. It runs once when the component is first rendered.

  • fetch: We use the fetch function to make a GET request to the API. The response.json() method converts the response into a JSON object.

  • FlatList: The FlatList component is used to display the list of posts. It’s highly efficient for rendering large lists.

Handling Errors

Always handle errors gracefully. In our example, we added a simple catch block to log errors. For a more user-friendly approach, you could display an error message in the UI:

const App = () => {
  const [posts, setPosts] = useState([]);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/posts')
      .then(response => response.json())
      .then(data => setPosts(data))
      .catch(error => {
        console.error('Error fetching data:', error);
        setError('Failed to load posts. Please try again.');
      });
  }, []);

  if (error) {
    return (
      <View style={styles.container}>
        <Text style={styles.error}>{error}</Text>
      </View>
    );
  }

  return (
    <View style={styles.container}>
      <Text style={styles.header}>Posts</Text>
      <FlatList
        data={posts}
        keyExtractor={item => item.id.toString()}
        renderItem={({ item }) => (
          <View style={styles.post}>
            <Text style={styles.title}>{item.title}</Text>
            <Text>{item.body}</Text>
          </View>
        )}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingTop: 50,
    paddingHorizontal: 20,
  },
  header: {
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 20,
  },
  post: {
    marginBottom: 20,
    padding: 20,
    backgroundColor: '#f9f9f9',
    borderRadius: 5,
  },
  title: {
    fontSize: 18,
    fontWeight: 'bold',
  },
  error: {
    fontSize: 18,
    color: 'red',
    textAlign: 'center',
    marginTop: 20,
  },
});

export default App;

Fetching data from an API is a crucial part of many applications. With React Native, it's straightforward and powerful. We've covered how to fetch data, display it, and handle errors gracefully.

In the next chapter, we’ll explore styling in React Native, helping you create beautiful and responsive designs for your app.

Keep coding!