Using useQuery within a custom hook

In our app, we make a request to retrieve some backend service information to be presented to the user. This info is used in more than one place in the UI. Previously, each of these places used useQuery to retrieve the relevant data (either from the network, or from cache). There’s a bit of setup and processing that needs to happen, so I thought of taking all that and creating a custom hook that will perform those actions, exposing the desired properties to be used throughout the app. My custom hook looks something like this:

export const useDevices = () => {
  const { data, error, loading } = useQuery(<gql here>, {
    variables: {
      tenantId: tenantId()
    },
    onError: (err) => showError(err.message)
  });

  return {
    devices: processData(data),
    error,
    loading
  };
};

This works great. It wraps this up nicely, so all I need to do to use it is const { devices, loading } = useDevices();.

My question revolves around how this really works. It’s a hook, so I imagine that every time a component that uses it renders, it creates another instance of useDevices. So is it calling the useQuery each time it’s instantiated?

Also, if for a particular view the hook is used in multiple places, that means there are multiple instances of useDevices existing at once. Each of those instances are calling useQuery. If this is the first time useQuery is called for a particular gql, then it should make a network request to fetch the data. But what about the other instances of useDevices? If they’re instantiated at about the same time as the first, do they report back “loading”, or would they also make network requests?

The ultimate goal is to use Apollo’s cache as a Redux store of sorts for many of the gql calls we make. We use the cache heavily, employing opportunistic updates often. Synching this with Redux (which we also use) is a bit of a pain, and since we already have the data, why not use that instead of getting Redux involved (or property drilling for that matter).

This would also be problematic for queries that poll, as I believe you’d end up with multiple instances of queries polling on different intervals.