We all know that react hooks cannot be invoked inside loops, conditions, or nested functions. As cited from the official docs:

React Hooks should not be called inside loops, conditions, or nested functions. They must be called at the top level of a React function component or custom hook. This rule is crucial for React to maintain the correct state and lifecycle behavior of components.

❗The Problem

But there are times we need to call a hook based on an array of values. For example, suppose we have an array of user IDs and we want to fetch information for each user. You might be tempted to do so:

 const allInfos = ids.map((id) => useGetUserInfo(id));

⚠️ This will immediately trigger a React Hook Rules Error because you’re calling a hook (useGetUserInfo) inside a loop (map).

✅ The Correct Approach

Instead of calling a hook inside a loop, you can build a new custom hook that takes an array of IDs and uses useQueries from react-query under the hood.

Here’s how you can structure it:

  1. Define the raw API call function, not a hook
 const fetchUserData = async (id) => {
   const response = await Axios.get(`/user${id}`);
   return response.data
 }
 
  1. Define a hook for fetching a single user's data:
function useGetUserInfo(id) {
   const fetchUser = () => fetchUserData(id);
   return useQuery(userKeys.single(id), fetchUser,{});
 }

This is for individual user fetching

  1. Define a custom hook for fetching multiple users:
function userGetMultipleUserInfo(ids) {
   const results = useQueries({
     queries: ids.map((id) => ({
       queryKey: userKeys.single(id),
       queryFn: () => fetchUserData(id),
     })),
   });
   return results.map((result) => result.data) 
 }

• useQueries lets you batch multiple queries cleanly inside one hook.

Now you can call:

  const allInfos = useGetMultipleUserInfo(ids)

The takeways are:

If you need to operate on arrays or dynamic values, build a custom hook to encapsulate the logic. React Query's useQueries is a great tool for handling multiple asynchronous queries at once.