Making HTTP API calls with Axios in React Native

Aug 5, 2023 ⋅ Modified: Aug 13, 2023 ⋅ 5 min read

Bilal Arslan

Hi there! I'm a full-stack developer who loves crafting web and mobile apps. When I'm not coding, I enjoy sharing my knowledge as a technical writer. Let's build something awesome together!

Introduction

Welcome to another insightful blog post. In today's tutorial, we will explore the process of making HTTP API calls in React Native. When building applications that require internet connectivity for fetching or posting data, utilizing HTTP calls becomes essential. For instance, we may need to request weather data, stock prices, or send user data to a server. Let's delve into this exciting project together.

Creating Project

  • First, let's set up our React Native project using Expo CLI:
npx create-expo-app react-native-axios
  • Next, navigate to the project directory:
cd react-native-axios

Installing Dependencies

  • We need to install several essential dependencies. Follow these steps:
npm install @react-navigation/native
npx expo install react-native-screens react-native-safe-area-context
npm install @react-navigation/native-stack
npm install axios

Starting the Emulator:

  • To launch the emulator, run the command:
npx expo start
  • The emulator is up and running!

Usage

  • Axios is a powerful promise-based HTTP Client used in Nodejs and browser environments. Since React Native is built on Nodejs, Axios can also be employed in React Native applications. For more information about Axios, you can refer to the official documentation link.

  • Using Axios is incredibly straightforward. Simply import Axios and use one of the following methods: GET, POST, PUT, or DELETE.

Get request with Axios

axios.get('/api/example')
    .then(function (response) {
        //when returns successfuly
        console.log(response);
    })
    .catch(function (error) {
        //when returns error
        console.log(error);
    })
    .then(function () {
        //always executed
    });

Post request with Axios

axios.post('/api/example', {
        title: title,
        description: description,
    })
    .then(function (response) {
        //when returns successfuly
        console.log(response);
    })
    .catch(function (error) {
        //when returns error
        console.log(error);
    });

Put request with Axios

axios.put('/api/example/1', {
        title: title,
        description: description,
    })
    .then(function (response) {
        //when returns successfuly
        console.log(response);
    })
    .catch(function (error) {
        //when returns error
        console.log(error);
    });

Delete request with Axios

axios.delete('/api/example')
    .then(function (response) {
        //when returns successfuly
        console.log(response);
    })
    .catch(function (error) {
        //when returns error
        console.log(error);
    });

Implementation

  • For the purpose of this blog post, we will build an e-commerce application that fetches product details from a server and displays them. However, to achieve this, we need an API server. We will utilize the Fake Store API for this demonstration.

  • Create a folder named src/screens and add two JSX files for HomeScreen and ProductScreen

// ./src/HomeScreen.jsx
 
import React from 'react'
import { View, Text } from 'react-native'
 
const HomeScreen = ({ route, navigation }) => {
    return (
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
            <Text>HomeScreen</Text>
        </View>
    )
}
 
export default HomeScreen;
// ./src/ProductScreen.jsx
 
import React from 'react'
import { View, Text } from 'react-native'
 
const ProductScreen = ({ route, navigation }) => {
    return (
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
            <Text>ProductScreen</Text>
        </View>
    )
}
 
export default ProductScreen;
  • Now, let's continue with App.js and import the screens we created.
// ./src/ProductScreen.jsx
 
import React from 'react';
import { StatusBar } from 'expo-status-bar';
import { SafeAreaProvider } from 'react-native-safe-area-context';
 
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
 
import HomeScreen from './src/screens/HomeScreen';
import ProductScreen from './src/screens/ProductScreen';
 
const Stack = createNativeStackNavigator();
 
export default function App() {
 
  return (
    <SafeAreaProvider style={{ flex: 1 }}>
      <StatusBar />
      <NavigationContainer>
        <Stack.Navigator initialRouteName='Home' screenOptions={{ headerShown: false }}>
          <Stack.Screen name='Home' component={HomeScreen} />
          <Stack.Screen name='Product' component={ProductScreen} />
        </Stack.Navigator>
      </NavigationContainer>
    </SafeAreaProvider>
  );
}
  • Next, we can create a service responsible for getting all products and retrieving a single product. Create a file under ./src/service named productService.js.
// ./src/service/productService
 
import axios from 'axios';
 
const API_URL = "https://fakestoreapi.com"
 
const getProducts = async () => {
    return new Promise((resolve, reject) => {
        axios.get(API_URL + '/products?limit=10')
            .then((res) => {
                console.log(res.data)
                resolve(res)
            })
            .catch((err) => {
                reject(err)
            });
    });
};
 
const getProductById = async (id) => {
    return new Promise((resolve, reject) => {
        axios.get(API_URL + '/products/' + id)
            .then((res) => {
                console.log(res.data)
                resolve(res)
            })
            .catch((err) => {
                reject(err)
            });
    });
};
 
export { getProducts, getProductById }
  • Now we have two functions that allow us to fetch product data and its details, enabling us to display them in the UI. Let's implement the HomeScreen to show products.
// ./src/screens/HomeScreen
 
import React, { useEffect, useState } from 'react'
import { View, Text, TouchableOpacity, FlatList, Image } from 'react-native'
import { AntDesign } from '@expo/vector-icons';
 
import { getProducts } from '../service/productService'
 
const HomeScreen = ({ route, navigation }) => {
 
    const [products, setProducts] = useState([])
 
    useEffect(() => {
 
        const fetchData = async () => {
            const data = await getProducts()
            setProducts(data)
 
        }
        fetchData();
 
    }, []);
 
    const navigateToProduct = (id) => {
        navigation.navigate('Product', { productId: id })
    }
 
    return (
        <View style={{ backgroundColor: '#dfe6ec', flex: 1, paddingHorizontal: 20, paddingVertical: 30 }}>
 
            <AntDesign name="tags" size={32} color="#797979" style={{ alignSelf: 'center', marginBottom: 16 }} />
 
            <FlatList
                data={products}
                renderItem={({ item }) =>
                    <TouchableOpacity key={item.id} style={{ backgroundColor: '#FFF', marginBottom: 32, padding: 12, borderRadius: 10 }}
                        onPress={() => navigateToProduct(item.id)}>
                        <AntDesign name="hearto" size={24} color="#71acf5" />
                        <Image
                            style={{ width: '100%', height: 250, resizeMode: 'contain', marginBottom: 12 }}
                            source={{ uri: item.image }}
                        />
 
                        <Text style={{ fontSize: 14, fontWeight: '600', color: '#797979' }}>{item.title}</Text>
                        <Text style={{ fontSize: 12, fontWeight: '300', marginTop: 8, color: '#797979' }}>{item.category.toUpperCase()}</Text>
                        <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginTop: 8 }}>
                            <View style={{ flexDirection: 'row', alignItems: 'center' }}>
                                <AntDesign name="star" size={20} color="#71acf5" />
                                <Text style={{ fontSize: 12, fontWeight: '600', color: '#797979', marginLeft: 4 }}>{item.rating.rate}</Text>
                            </View>
 
                            <Text style={{ fontSize: 16, fontWeight: '600', color: '#71acf5' }}>{'$' + item.price}</Text>
                        </View>
 
                        <TouchableOpacity style={{ padding: 8, justifyContent: 'center', alignItems: 'center', borderWidth: 2, borderColor: '#71acf5', marginTop: 12, borderRadius: 10 }}>
                            <Text style={{ fontSize: 14, fontWeight: '600', color: '#71acf5' }}>Add To Cart</Text>
                        </TouchableOpacity>
                    </TouchableOpacity>
                }
                keyExtractor={item => item.id}
            />
 
        </View>
    )
}
 
export default HomeScreen;
Home Screen E Commerce App
  • When a product is selected, navigate to the ProductScreen and pass the productId as a parameter. This way, we can make a GET request with the product ID to fetch its details.
// ./src/screens/ProductScreen
 
import React, { useEffect, useState } from 'react'
import { View, Text, Image, TouchableOpacity } from 'react-native'
import { AntDesign } from '@expo/vector-icons';
 
import { getProductById } from '../service/productService'
 
const ProductScreen = ({ route, navigation }) => {
 
 
    const { productId } = route.params;
    const [product, setProduct] = useState(null)
 
    useEffect(() => {
 
        const fetchData = async () => {
            const data = await getProductById(productId)
            setProduct(data)
        }
        fetchData();
 
    }, []);
 
    return (
        <View style={{ backgroundColor: '#dfe6ec', flex: 1, paddingHorizontal: 20, paddingVertical: 30 }}>
            <AntDesign name="tags" size={32} color="#797979" style={{ alignSelf: 'center', marginBottom: 16 }} />
 
            {product &&
                <View style={{ flex: 1 }}>
                    <View style={{ flex: 1, backgroundColor: '#FFF', marginVertical: 8, borderRadius: 10, padding: 30 }}>
                        <Text style={{ fontSize: 16, fontWeight: '600', color: '#797979', textAlign: 'center' }}>{product.title}</Text>
                        <Text style={{ fontSize: 12, fontWeight: '300', marginTop: 8, color: '#797979', textAlign: 'center' }}>{product.category.toUpperCase()}</Text>
 
                        <Image
                            style={{ width: '100%', height: 250, resizeMode: 'contain', }}
                            source={{ uri: product.image }}
                        />
 
                        <Text style={{ flex: 1, fontSize: 14, fontWeight: '400', marginTop: 16, color: '#797979', textAlign: 'center' }}>{product.description}</Text>
                        <View style={{ flexDirection: 'row', alignItems: 'center', alignSelf: 'center', marginTop: 24 }}>
                            <AntDesign name="star" size={20} color="#71acf5" />
                            <Text style={{ fontSize: 12, fontWeight: '600', color: '#797979', marginLeft: 4 }}>{product.rating.rate}</Text>
                        </View>
                        <Text style={{ fontSize: 18, fontWeight: '600', color: '#71acf5', textAlign: 'center', marginTop: 8, }}>{'$' + product.price}</Text>
                    </View>
                    <TouchableOpacity style={{ padding: 12, justifyContent: 'center', alignItems: 'center', backgroundColor: '#71acf5', borderWidth: 2, borderColor: '#FFF', marginTop: 4, borderRadius: 10 }}>
                        <Text style={{ fontSize: 14, fontWeight: '600', color: '#FFF' }}>Buy Now</Text>
                    </TouchableOpacity>
                </View>
            }
 
        </View>
    )
}
 
export default ProductScreen;
Product Screen E Commerce App
  • Here it is, we have an application that get product details from server with using HTTP API calls.

Source Code

Github Repository Link

Project Dependencies

"dependencies": {
    "@react-navigation/native": "^6.1.7",
    "@react-navigation/native-stack": "^6.9.13",
    "axios": "^1.4.0",
    "expo": "~49.0.5",
    "expo-status-bar": "~1.6.0",
    "react": "18.2.0",
    "react-native": "0.72.3",
    "react-native-safe-area-context": "4.6.3",
    "react-native-screens": "~3.22.0"
  }

Conclusion

  • We implemented an e-commerce application, demonstrating fetching product details from a server and display them in the user interface. Throughout the tutorial, we utilized the Fake Store API to illustrate the concepts effectively.

  • In this tutorial, we focused on GET requests, but Axios offers support for other HTTP methods like POST, PUT, DELETE, and header configurations. For more comprehensive tutorials on these topics, stay tuned for my upcoming posts.