Search code examples
javascriptajaxreactjsfetchsetstate

How to setState in React only after multiple fetches inside a loop are resolved


In a React application, I'm trying to setState in my App only after I get lots of AJAX fetches resolved to avoid multiple useless re-rendering.

I have something like this so far:

const URL = https://url/api/
const NUM_OF_ITEMS = 10;
let allData = [];

componentDidMount() {
  for (let i = 1; i <= NUM_OF_ITEMS; i++) {
    this.fetchData(`${URL}${i}/`)  //ex. https://url/api/1/, https://url/api/2/...
  }
}

const fetchData = URI => {
  fetch(URI)
  .then(response => response.json())
  .then(data => {
    allData = [ ...allData, data];
  })
  .catch( error => this.setState({ error });
}

Now I wanted to have just one single setState after all fetches are all resolved, and then save it all into localStorage:

this.setState({ allData })
localStorage.setItem("allData", JSON.stringify(allData))

Any ideas on how to do it?


Solution

  • You want to use Promise.all:

    componentDidMount() {
      const requests = [];
      for (let i = 1; i <= NUM_OF_ITEMS; i++) {
        requests.push(this.fetchData(`${URL}${i}/`));
      }
      Promise.all(requests).then((arrayWithData) => {
         // here you can use setState with all the stuff
      });
    }
    
    const fetchData = URI => {
      fetch(URI)
      .then(response => response.json())
    }