React Native provides the Fetch API for making HTTP requests. It follows the web standard Fetch API specification.
Overview
The Fetch API provides a JavaScript interface for accessing and manipulating parts of the HTTP pipeline, such as requests and responses. It also provides a global fetch() method that provides an easy, logical way to fetch resources asynchronously across the network.
Global Objects
React Native exposes the following global objects from the Fetch API:
fetch - Method for making network requests
Headers - Constructor for creating HTTP headers
Request - Constructor for creating request objects
Response - Constructor for creating response objects
fetch()
fetch(url: string, options?: object): Promise<Response>
Makes an HTTP request and returns a Promise that resolves to a Response object.
The URL to send the request to
Optional configuration for the requestHTTP method: GET, POST, PUT, DELETE, PATCH, etc.
HTTP headers to include in the request
Request body. Not used for GET or HEAD requests.
Request mode: cors, no-cors, same-origin
Credentials mode: omit, same-origin, include
Cache mode: default, no-store, reload, no-cache, force-cache, only-if-cached
Redirect mode: follow, error, manual
AbortSignal to cancel the request
Returns: Promise<Response> - Resolves to a Response object
Response Object
The Response object represents the response to a request.
Properties
true if status is in the range 200-299
HTTP status code (e.g., 200, 404, 500)
Status message corresponding to the status code
Headers object containing response headers
Type of response: basic, cors, error, opaque
Methods
Parses the response body as JSONReturns: Promise<any>
Reads the response body as textReturns: Promise<string>
Reads the response body as a BlobReturns: Promise<Blob>
Parses the response body as FormDataReturns: Promise<FormData>
Reads the response body as an ArrayBufferReturns: Promise<ArrayBuffer>
Examples
Basic GET Request
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => {
console.log(data);
})
.catch(error => {
console.error('Error:', error);
});
GET with async/await
async function fetchData() {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Error:', error);
}
}
POST Request with JSON
const postData = async () => {
try {
const response = await fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'John Doe',
email: '[email protected]',
}),
});
const data = await response.json();
console.log('Success:', data);
} catch (error) {
console.error('Error:', error);
}
};
Handling Different Status Codes
const fetchWithErrorHandling = async () => {
try {
const response = await fetch('https://api.example.com/data');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Error:', error);
}
};
import {launchImageLibrary} from 'react-native-image-picker';
const uploadImage = async () => {
const result = await launchImageLibrary({mediaType: 'photo'});
if (result.assets && result.assets[0]) {
const formData = new FormData();
formData.append('photo', {
uri: result.assets[0].uri,
type: result.assets[0].type,
name: result.assets[0].fileName,
});
try {
const response = await fetch('https://api.example.com/upload', {
method: 'POST',
body: formData,
headers: {
'Content-Type': 'multipart/form-data',
},
});
const data = await response.json();
console.log('Upload success:', data);
} catch (error) {
console.error('Upload error:', error);
}
}
};
const fetchWithHeaders = async () => {
const headers = new Headers();
headers.append('Authorization', 'Bearer your-token-here');
headers.append('Accept', 'application/json');
try {
const response = await fetch('https://api.example.com/protected', {
method: 'GET',
headers: headers,
});
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Error:', error);
}
};
Timeout with AbortController
const fetchWithTimeout = async (url, timeout = 5000) => {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, {
signal: controller.signal,
});
clearTimeout(timeoutId);
return await response.json();
} catch (error) {
if (error.name === 'AbortError') {
console.log('Request timed out');
} else {
console.error('Error:', error);
}
}
};
PUT Request
const updateUser = async (userId, userData) => {
try {
const response = await fetch(`https://api.example.com/users/${userId}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(userData),
});
if (!response.ok) {
throw new Error('Update failed');
}
const data = await response.json();
return data;
} catch (error) {
console.error('Error:', error);
throw error;
}
};
DELETE Request
const deleteUser = async (userId) => {
try {
const response = await fetch(`https://api.example.com/users/${userId}`, {
method: 'DELETE',
});
if (!response.ok) {
throw new Error('Delete failed');
}
return true;
} catch (error) {
console.error('Error:', error);
return false;
}
};
React Hook for Fetching Data
import {useState, useEffect} from 'react';
function useApi(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json();
setData(result);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);
return {data, loading, error};
}
// Usage
function MyComponent() {
const {data, loading, error} = useApi('https://api.example.com/data');
if (loading) return <Text>Loading...</Text>;
if (error) return <Text>Error: {error}</Text>;
return <Text>{JSON.stringify(data)}</Text>;
}
Notes
- Fetch is based on the
whatwg-fetch polyfill
- Does not reject on HTTP error status (404, 500, etc.) - check
response.ok or response.status
- CORS policies apply when making requests to different domains
- iOS requires HTTPS by default (configure App Transport Security to allow HTTP)
- Consider using libraries like
axios for more features (interceptors, automatic retries, etc.)
- Always handle errors appropriately
- Be mindful of network conditions on mobile devices