Introduction to the
When building web or mobile applications, you often need to make network requests to apis. You can use these web requests to authenticate users, update resources, or obtain resources from your own server or third-party apis. The Fetch API comes in handy if you want to make API requests in a browser environment.
React Native also has a browser-like built-in Fetch API designed specifically for networking with the API from your mobile app. However, there are alternative libraries, such as Axios, that you can use instead of relying on the native Fetch API.
If you just want to retrieve resources from the server, the built-in Fetch API is probably sufficient. For more complex network requirements, Axios may be a better choice because it comes with additional features, such as intercepting network requests and responses.
Also, among other reasons, most developers prefer Axios to the built-in FETCH API because of its isomorphism and out-of-the-box JSON transformations.
In this article, you’ll learn how to use Axios to manage API requests in React Native applications.
Axios profile
Axios is a popular, homogeneous HTTP client. This means it can run in a browser and Node runtime environment. Therefore, you can use the same code base for API requests in Node, browser, and React Native.
Axios has several features, such as support for the Promise API, automatic JSON transformations, and interception of web requests and responses.
Use the Expo CLI to set up a simple React Native application
In this tutorial, we’ll use a simple React Native application set up using Expo’s managed workflow.
If you’ve already set up a React Native app, you can continue to the next section. Otherwise, there are setup instructions for the workflow managed by Expo in the React Native documentation that will get you up and running in minutes.
Axios profile
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 calling the appropriate method with the necessary parameters. You’ll learn the basics of Axios in this section.
The features highlighted in the following sections are the ones you’ll use most often when using Axios.
How do I install Axios
Depending on which package manager you are using, type one of the following commands in the terminal window and then hit the Back key to install Axios.
// axios
npm install axios
// yarn
yarn add axios
Copy the code
How do I use Axios to make requests to the API
When calling the API using Axios, you can pass Axios a configuration object or call a method for the corresponding CRUD operation you want to perform.
For example, you can make a GET request to the/API/Users endpoint in one of two ways.
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);
});
Copy the code
You can also use async/await instead of using the Promise chain as in the example above.
There are several other fields, such as the baseURL, transformRequest, transformResponse, and headers, etc., you can pass to Axios configuration object contained in these fields.
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);
};
Copy the code
Unlike the built-in Fetch API, Axios will convert the response to JSON for you, not out of the box.
How do I make multiple concurrent API requests using Axios
You can make multiple concurrent API requests from the React Native application using the Promise.all or Promise.AllSettled method of the Axios Promise API.
In the following snippet, all API requests succeed; Change the URI passed to the axios.get method to one that doesn’t exist and see what happens if some of the requests don’t succeed.
const concurrentRequests = [
axios.get(`${baseUrl}/api/users/1`),
axios.get(`${baseUrl}/api/users/2`),
axios.get(`${baseUrl}/api/users/3`),
];
// Using Promise.all
Promise.all(concurrentRequests)
.then((result) => {
console.log(result);
})
.catch((err) => {
console.log(err);
});
// Using Promise.allSettled
Promise.allSettled(concurrentRequests)
.then((result) => {
console.log(result);
})
.catch((err) => {
console.log(err);
});
Copy the code
Note that if one of the entered promises is rejected, the promise.all method immediately rejects it. If you want to see all or none of the API requests succeed, use promise.all.
Promise.allsettled, on the other hand, waits for all input promises to be rejected or satisfied. Then, you can check the fulfilled or Rejected state of each response object.
How do I abort a network request in Axios
Axios provides the ability to abort network requests. A typical use case for this feature in React Native is to cancel the network request in the useEffect hook when a component is unloaded while data is still flying.
You can read the code snippet below to learn how to use this feature.
useEffect(() => {
const source = axios.CancelToken.source();
const url = `${baseUrl}/api/users/${userId}`;
const fetchUsers = async () => {
try {
const response = await axios.get(url, { cancelToken: source.token });
console.log(response.data);
} catch (error) {
if(axios.isCancel(error)){
console.log('Data fetching cancelled');
}else{
// Handle error
}
}
};
fetchUsers();
return () => source.cancel("Data fetching cancelled");
}, [userId]);
Copy the code
How do I create an instance of Axios
You can also create an instance of Axios with a custom configuration. The network request is then made using the method exposed by the example.
Axios merges the configuration object passed when the instance is created 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);
});
Copy the code
Use Axios and React Native to manage API requests
In this section, you’ll learn how to use Axios to manage API requests in React Native applications. You’ll use Axios to perform a simple CRUD (Create, read, update, delete) operation.
How to manage API keys in React Native
Most third-party apis require a secret certificate to access. Keeping your secret API keys in the client’s source code is not a good idea. If you do, your private key can be accessed by anyone who examines the code of your bundled apps.
One of the recommended ways to manage your API keys is to create a coordination layer between third-party apis and your application. For example, you can use a serverless function to securely access your API keys.
Your application will call the endpoint exposed by the serverless function. The serverless function will securely access your API key, call a third-party API, retrieve the resources you need, and forward them to your mobile application.
Manages application status in the network request-response cycle
When you make a network request to an API, the request either succeeds or fails. Therefore, it is important to keep track of the different states of your application from the request to the response received from the server.
You can display a loading indicator while the data is still flying. If the CRUD operation succeeds, you display a “success” message to the user. If it fails, you will display an appropriate error message.
This is important because customers using your application may have a slow Internet connection or no Internet access. The API server may sometimes experience outages. Tracking the status of your application and displaying the appropriate information will provide a good user experience.
We will use the reqresREST API in this article. It is a placeholder API made up of fake data. You can use API testing tools such as Postman or Insomnia to play around with these endpoints.
How to use Axios to make GET requests in React Native
In this section, we will make a GET request to the/API/Users endpoint to retrieve a user. If you want to request a resource from a server, GET is the HTTP method you use.
As shown in the code snippet below, we store the user ID in the state. You can change the User ID in the onPress event handler connected to the Load User button. Changing the user ID will trigger a GET request to the useEffect hook API.
When the network request is triggered, we display a load metric on the screen. If we successfully retrieve the data, we update the status and remove the load indicator. If we can’t get the data for any reason, we stop loading the indicator and display an appropriate error message.
If the user decides to shut down the application before getting a response from the server, we abort the network request in the cleanup function. Check the return value of the effect function in the useEffect hook.
Here’s what the code looks like in the app.js component.
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, }, });Copy the code
In the above component, we use the useEffect hook to perform side effects, such as retrieving data from the API. However, this may change in future versions of React. You can check out the React documentation for more information about React Suspense; This is a data capture feature that will soon appear in a stable version of React.
How to use Axios for POST requests in React Native
In this section, you will learn how to make POST requests. POST is an HTTP method used to send data to the server to update or create resources.
The placeholder API we used exposes the/API/Users endpoint for creating the resource. After successfully creating the resource, you will get a response with a 201 status code.
Issuing a POST request in Axios is similar to issuing a GET request. In most cases, A POST request is submitted through a form with user-generated data. The submitted data can be from the customer’s login, registration, or feedback form. This data needs to be validated on the client side before submission.
When building a complex application, you can use one of these forms packages for data validation. Most packages are well structured and optimized, and have a good community behind them. However, before integrating a library into your application, explore the pros and cons. In particular, the size of the extra packages you add to your application and the potential security holes it may introduce.
There are two main React packages for managing forms. These packages are Formik and React Hook Form. If you’re interested, you can find many articles about form validation in React.
We set up a React Native form for the user’s full name and email in the code snippet below. TextInput, both of which are controlled components. Ideally, you’ll validate the data in real time as the user fills out the form. This is not the case here, however, because form data validation is outside the scope of this article.
After clicking the Submit button, the TextInput field and the submit button are disabled, and a message is displayed indicating that you are creating the resource. Disabling the submit button ensures that users do not commit multiple times.
After a successful POST request is submitted, you will 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, }, });Copy the code
How to use Axios to make PUT requests in React Native
Updating a resource requires the PUT or PATCH method, but I’ll focus on PUT.
If a resource exists, the PUT method overwrites it completely, and if it does not, a new resource is created. On the other hand, PATCH partially updates the resource if it exists, and does nothing if it doesn’t.
Making a PUT request to an API is similar to making a POST request. The only difference is the configuration object you pass to Axios, or the HTTP method you need to call to make a PUT request to the API.
You can replace the onSubmitFormHandler in the POST request with the following code to make the PUT request. For completeness, I use the Promise chain instead of async/await in the event handler below.
const onSubmitFormHandler = (event) => { if (! fullName.trim() || ! email.trim()) { alert("Name or Email is invalid"); return; } setIsLoading(true); const configurationObject = { url: `${baseUrl}/api/users/2`, method: "PUT", data: { fullName, email }, }; axios(configurationObject) .then((response) => { if (response.status === 200) { alert(` You have updated: ${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); }); };Copy the code
How to make a DELETE request with Axios in React Native
You can do DELETE requests with Axios just like you do POST and PUT requests.
As its name suggests, a DELETE request removes a resource from the server side. You can implement the DELETE request by replacing the POST request code onSubmitFormHandler with the following event handler. The rest of the code remains the same.
const onSubmitFormHandler = async (event) => { if (! fullName.trim() || ! email.trim()) { alert("Name or Email is invalid"); return; } setIsLoading(true); try { const response = await axios.delete(`${baseUrl}/api/users/2`, { fullName, email, }); if (response.status === 204) { alert(` You have deleted: ${JSON.stringify(response.data)}`); setIsLoading(false); setFullName(''); setEmail(''); } else { throw new Error("Failed to delete resource"); } } catch (error) { alert("Failed to delete resource"); setIsLoading(false); }};Copy the code
conclusion
When you’re building a mobile application, making network requests to the API is inevitable, and Axios is one of the most popular HTTP clients out there. It comes with additional features that make networking as simple as possible.
The API with which your application interacts can be self-hosted or third-party. Effective management of the network request-response cycle is of Paramount importance in order to improve user experience.
Conversely, you need to weigh the pros and cons of adding a third-party package like Axios to your mobile app. Although Axios is a popular, well-maintained package, it will increase the size of your package by 367kB, according to Packagephobia.
Although the size of this package may seem like a small addition to your application when using a powerful mobile device, you need to consider its impact on users using less powerful mobile devices. Likewise, you need to make sure that third-party packages like Axios don’t expose your application to security vulnerabilities.
The postUsing Axios with React Native to manage API requestsappeared first onLogRocket Blog.