Skip to content

How to useFetch with a for loop?

I am creating an application with react. I have to fetch several data. This is my fetch statement:

const [periods] = useFetch('/company/' + slug + '/waterfall?colIndexOffset=6 ');

At the end of the line, it is a 6 but I have this kind of problem. I have periods and these periods are changed for every object.

const [period_waterfall] = useFetch('/company/' + firminfo.code + '/periods');

I call the period from there and I find the length of periods like this:

var length = period_waterfall.periods.length

I should call this periods fetch multiple times (number of length).

I tried this:

for (let i = 0; i < length; i++) {
        my_array.push(useFetch('/company/' + slug + '/waterfall?colIndexOffset=' + i))
      }

But it gives error: React Hook “useFetch” may be executed more than once. Possibly because it is called in a loop.

How can I handle it?

Answer

You’re trying to call a hook within a loop. This is a bad practice and is not allowed. Hooks should always be called at the top level.

You’re also using a predefined hook for data retrieval. This hook is meant to do one fetch. In your particular order, you need to do this in a loop operation, which means the hook you’re using doesn’t fit your need.

What you can do, is create a function that does the fetching instead of using the hook. I like to use axios.

const getPeriods = async (offset, slug) => {
  const url = '/company/' + slug + '/waterfall?colIndexOffset=' + offset
  const response = await axios.get(url)
  return response.data
}

In this function, you are fetching 1 item. You may rewrite it so that you do the looping inside of it, or you can call it inside a loop

for (let i = 0; i < length; i++) {
  my_array.push(await getPeriods(i, slug)
}

Note that the loop is using await which means it needs to be inside an async function. If you don’t want that, you can always do something like this:

getPeriods(i, slug).then((res) => {
  my_array.push(res.data)
}

Hope this helps solving your issue.