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.
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
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
To launch the emulator, run the command:
npx expo start
The emulator is up and running!
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.
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
});
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);
});
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);
});
axios. delete ( '/api/example' )
. then ( function ( response ) {
//when returns successfuly
console. log (response);
})
. catch ( function ( error ) {
//when returns error
console. log (error);
});
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;
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;
Here it is, we have an application that get product details from server with using HTTP API calls.
Github Repository Link
"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"
}
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.