Basically I have a screen that calls multiple APIs at componentDidMount
, and each and every API will fire a network request along with a callback, something as below
componentDidMount() {
new APIManager.fetchBooks(this.handleBooks);
new APIManager.fetchAuthor(this.handleAuthor);
new APIManager.fetchShops(this.handleShops);
}
...
handleBooks = (result) => {
this.setState({ books: result });
}
...
And basically all the fetch
methods works pretty similarly, it accepts a single parameter which is a callback from the component, pseudocode as below
export async function fetchBooks(callback) {
const result = await callNetworkAPI();
callback(result);
}
This was working fine on both Android and iOS at react-native v0.53 but it's not working anymore at v0.59.10 on iOS.
What's happening now is that, fetchBooks
, fetchAuthor
and fetchShops
will all still be triggered but this.handleBooks
, this.handleAuthor
will no longer be triggered. It's like they lost their cursor.
I've made it work such that all API calls has to be using await
, something as below
async componentDidMount() {
const books = await APIManager.fetchBooks();
const authors = await APIManager.fetchAuthor();
const shops = await APIManager.fetchShops();
this.handleBooks(books);
this.handleAuthors(authors);
this.handleShops(shops);
}
And of course updates to my APIManager
as below:
export async function fetchBooks() {
const result = await callNetworkAPI();
return result;
}
Its working fine, but all 3 API calls cannot be asynchronously anymore because I made it await for the previous API call before proceeding. I'm wondering if there's a better way to handle my problem? Or I'm totally on the right track?
If you want to call multiple API calls simultaneously, there's a better approach using Promise. all() . But if one API calls requires data from another, returning the fetch() method like this provides a simple, readable, flat structure and let's you use a single catch() for all of your API calls.
If you need to make multiple API requests, you can send these API requests concurrently instead of sending them one by one. Sometimes, we need to make multiple API calls at once. For example, let's say we have an array, and we want to make an API request for each element of that array.
Hope so It will help you for multiple API calls simultaneously.
React.useEffect(()=>{
Promise.all([
fetch('https://jsonplaceholder.typicode.com/posts'),
fetch('https://jsonplaceholder.typicode.com/users')
]).then(function (responses) {
// Get a JSON object from each of the responses
return Promise.all(responses.map(function (response) {
return response.json();
}));
}).then(function (data) {
// Log the data to the console
// You would do something with both sets of data here
console.log(data);
}).catch(function (error) {
// if there's an error, log it
console.log(error);
});
},[])
You could use Promise.all
to wait for multiple requests in parallel:
async componentDidMount() {
const [books, authors, shops] = await Promise.all([
APIManager.fetchBooks(),
APIManager.fetchAuthor(),
APIManager.fetchShops(),
]);
this.handleBooks(books);
this.handleAuthors(authors);
this.handleShops(shops);
}
This however waits for all 3 requests to be completed before calling handleBooks
/ handleAuthors
/ handleShops
.
If you want them to call their handle method directly after they completed, you could use .then()
on the individual fetch calls:
async componentDidMount() {
await Promise.all([
APIManager.fetchBooks().then(this.handleBooks),
APIManager.fetchAuthor().then(this.handleAuthors),
APIManager.fetchShops().then(this.handleShops),
]);
// All fetch calls are done now
console.log(this.state);
}
(this works because async
functions always return a promise)
About your problem with the fetch calls, you might be affected by this react-native
bug:
Multiple fetch request starts to not resolve or reject promise
According to the github issue page, it should be fixed in version 1.2.1
of react-native
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With