
Introduction
React Native also has a built-in Fetch API similar to the browser’s, specifically for networking with an API from your mobile application. However, there are alternative libraries, such as Axios, that you can use instead of relying on the native Fetch API.
The built-in fetch API might suffice if you only want to retrieve a resource from the server. Axios may be a better option for more complex networking requirements because it comes with additional features, such as the interception of network requests and responses.
Introduction to Axios
Axios is a popular, isomorphic HTTP client. That means it can run in the browser and the Node runtime environment. As a result, you can use the same codebase for making API requests in Node, in the browser, and in React Native.
Axios has several features such as support for the Promise API, automatic JSON transformation, and interception of network requests and responses, among others.
Axios is one of the easiest HTTP clients to learn and use. Making an API request is as simple as passing a configuration object to Axios or invoking the appropriate method with the necessary arguments. You will learn the basics of Axios in this section.
Install Axios
`// axios
npm install axios
// yarn
yarn add axios`
Make requests to an API using Axios
When making a call to an API using Axios, you can pass a configuration object to Axios or invoke a method for the corresponding CRUD operation you want to perform.
`import axios from ‘axios’;
const baseUrl = ‘https://reqres.in’;
// Passing configuration object to axios
axios({
method: ‘get’,
url: ${baseUrl}/api/users/1
,
}).then((response) => {
console.log(response.data);
});
// Invoking get method to perform a GET request
axios.get(${baseUrl}/api/users/1
).then((response) => {
console.log(response.data);
});`
There are several other fields such as baseURL, transformRequest, transformResponse, and headers, among others, which you can include in the configuration object you pass to Axios:
The features highlighted in the following sub-sections are the most common features you will use when working with Axios.
`import axios from ‘axios’;
const baseUrl = ‘https://reqres.in’;
// Passing configuration object to axios
const fetchUser = async () => {
const configurationObject = {
method: ‘get’,
url: ${baseUrl}/api/users/1
,
};
const response = await axios(configurationObject);
console.log(response.data);
};
// Invoking get method to perform a GET request
const fetchUser = async () => {
const url = ${baseUrl}/api/users/1
;
const response = await axios.get(url);
console.log(response.data);
};`
How to create an instance of Axios
You can also create an instance of Axios with a custom configuration. Then, use the methods exposed by the instance to make network requests.
Axios will merge the configuration object passed while creating the instance with the configuration passed to the instance method:
`const axiosInstance = axios.create({ baseURL: ‘https://reqres.in/’ });
axiosInstance.get(‘api/users/1’).then((response) => {
console.log(response.data);
});`
Using Axios with React Native to manage API requests
In this section, you will learn to manage API requests using Axios in a React Native application. You will use Axios to perform a simple CRUD (Create, Read, Update, and Delete) operation.
How to make GET request using Axios in React Native
We are storing the user ID in state as shown in the code snippet below. You can change the user ID inside the onPress event handler attached to the Load User button. Changing the user ID will trigger a GET request to the API inside the useEffect hook.
After triggering a network request, we display a loading indicator on the screen. If we fetch the data successfully, we update state and remove the loading indicator. If we fail to retrieve the data for some reason, we stop the loading indicator and display an appropriate error message.
We abort the network request in the cleanup function if the user decides to close the app before getting a response from the server. Check the return value of the effect function in the useEffect hook.
import axios from "axios";
import React, { useState, useEffect } from "react";
import {
StyleSheet,
Text,
ScrollView,
View,
Button,
Image,
Platform,
} from "react-native";
import Constants from "expo-constants";
const baseUrl = "https://reqres.in";
function User({ userObject }) {
return (
<View>
<Image
source={{ uri: userObject.avatar }}
style={{ width: 128, height: 128, borderRadius: 64 }}
/>
<Text style={{ textAlign: "center", color: "white" }}>
{
${userObject.first_name} ${userObject.last_name}}
</Text>
</View>
);
}
export default function App() {
const [userId, setUserId] = useState(1);
const [user, setUser] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [hasError, setErrorFlag] = useState(false);
const changeUserIdHandler = () => {
setUserId((userId) => (userId === 3 ? 1 : userId + 1));
};
useEffect(() => {
const source = axios.CancelToken.source();
const url =
${baseUrl}/api/users/${userId};
const fetchUsers = async () => {
try {
setIsLoading(true);
const response = await axios.get(url, { cancelToken: source.token });
if (response.status === 200) {
setUser(response.data.data);
setIsLoading(false);
return;
} else {
throw new Error("Failed to fetch users");
}
} catch (error) {
if(axios.isCancel(error)){
console.log('Data fetching cancelled');
}else{
setErrorFlag(true);
setIsLoading(false);
}
}
};
fetchUsers();
return () => source.cancel("Data fetching cancelled");
}, [userId]);
return (
<ScrollView contentContainerStyle={styles.container}>
<View style={styles.wrapperStyle}>
{!isLoading && !hasError && user && <User userObject={user} />}
</View>
<View style={styles.wrapperStyle}>
{isLoading && <Text> Loading </Text>}
{!isLoading && hasError && <Text> An error has occurred </Text>}
</View>
<View>
<Button
title="Load user"
onPress={changeUserIdHandler}
disabled={isLoading}
style={styles.buttonStyles}
/>
</View>
</ScrollView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "dodgerblue",
alignItems: "center",
justifyContent: "center",
marginTop: Platform.OS === "ios" ? 0 : Constants.statusBarHeight,
},
wrapperStyle: {
minHeight: 128,
},
buttonStyles: {
padding: 100,
},
});
How to make POST request using Axios in React Native
The placeholder API we are using exposes the /api/users endpoint for creating a resource. You will get a response with a 201 status code after successfully creating the resource.
Making a POST request in Axios is similar to making a GET request. Most of the time, POST requests are made with user-generated data submitted using a form. The submitted data can be from log in, sign up, or feedback forms from your clients. Such data requires validation on the client side before it is submitted.
You can use one of the form packages for data validation when building a complex applications. Most of the packages are well architected and optimized, and have a great community behind them. However, before integrating a library in your application, explore the tradeoffs. Especially the additional bundle size you are adding to your app, and potential security vulnerabilities it might introduce.
There are two main React packages for managing forms. These packages are Formik and React Hook Form. You can find plenty of articles on form validation in React if you are interested.
We have a React Native form for the user’s full name and email in the code snippet below. Both TextInput components are controlled components. Ideally, as the user fills the form, you perform data validation in real time. However, that is not the case here, because form data validation is outside the scope of this article.
After clicking the submit button, the TextInput fields and the submit button are disabled before you display a message to show you are creating the resource. Disabling the submit button ensures the user doesn’t make multiple submissions.
After successfully submitting a POST request, you display a success message to the user:
`import axios from “axios”;
import React, { useState } from “react”;
import {
StyleSheet,
Text,
ScrollView,
View,
Button,
Platform,
TextInput,
} from “react-native”;
import Constants from “expo-constants”;
const baseUrl = “https://reqres.in”;
export default function App() {
const [fullName, setFullName] = useState("");
const [email, setEmail] = useState("");
const [isLoading, setIsLoading] = useState(false);
const onChangeNameHandler = (fullName) => {
setFullName(fullName);
};
const onChangeEmailHandler = (email) => {
setEmail(email);
};
const onSubmitFormHandler = async (event) => {
if (!fullName.trim() || !email.trim()) {
alert(“Name or Email is invalid”);
return;
}
setIsLoading(true);
try {
const response = await axios.post(${baseUrl}/api/users
, {
fullName,
email,
});
if (response.status === 201) {
alert(You have created: ${JSON.stringify(response.data)}
);
setIsLoading(false);
setFullName('');
setEmail('');
} else {
throw new Error(“An error has occurred”);
}
} catch (error) {
alert(“An error has occurred”);
setIsLoading(false);
}
};
return (
<ScrollView contentContainerStyle={styles.container}>
<View>
<View style={styles.wrapper}>
{isLoading ? (
<Text style={styles.formHeading}> Creating resource </Text>
) : (
<Text style={styles.formHeading}>Create new user</Text>
)}
</View>
<View style={styles.wrapper}>
<TextInput
placeholder=“Full Name”
placeholderTextColor=“#ffffff”
style={styles.input}
value={fullName}
editable={!isLoading}
onChangeText={onChangeNameHandler}
/>
</View>
<View style={styles.wrapper}>
<TextInput
placeholder=“Email”
placeholderTextColor=“#ffffff”
style={styles.input}
value={email}
editable={!isLoading}
onChangeText={onChangeEmailHandler}
/>
</View>
<View>
<Button
title=“Submit”
onPress={onSubmitFormHandler}
style={styles.submitButton}
disabled={isLoading}
/>
</View>
</View>
</ScrollView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: “#252526”,
alignItems: “center”,
justifyContent: “center”,
marginTop: Platform.OS === “ios” ? 0 : Constants.statusBarHeight,
},
formHeading: {
color: “#ffffff”,
},
wrapper: {
marginBottom: 10,
},
input: {
borderWidth: 2,
borderColor: “grey”,
minWidth: 200,
textAlignVertical: “center”,
paddingLeft: 10,
borderRadius: 20,
color: “#ffffff”,
},
submitButton: {
backgroundColor: “gray”,
padding: 100,
},
});`
Conclusion
Making network requests to an API is inevitable when you are building a mobile application, and Axios is one of the most popular HTTP clients out there. It comes with added functionalities, making networking as simple as possible.
The APIs your app interacts with can be self hosted or third party APIs. For improved user experience, effective management of the network request-response cycle is paramount.
On the flip side, you need to weigh the tradeoffs of adding third party packages like Axios to your mobile application. Though Axios is a popular and well-maintained package, it will increase your bundle size by 367kB according to Packagephobia.