This video is available to students only

How to Customize the React useQuery Hook

With React's useState and useEffect Hooks, we've been able to query and display listings information the moment our Listings component is mounted. In this lesson, we'll create our very own custom useQuery Hook that will consolidate the pattern of creating a state property, using the useEffect Hook, and running the server fetch() function to make a query and state update when a component mounts.

Custom useQuery Hook#

📝 This lesson's quiz can be found - here.
🗒️ Solutions for this lesson's quiz can be found - here.

React's useEffect Hook helped us achieve the desired result of displaying listings information the moment our <Listings> component mounts.

The pattern of creating a state property, using the useEffect Hook, and running the server.fetch() function to make our query on mount will be replicated for every component that might want to fetch data the moment the component mounts. We can create a custom Hook that will help consolidate this pattern for all components.

Custom Hooks in React allows us to share logic between components and with best practice should have the use keyword in its name. Custom Hooks can also call other Hooks as well!


Let's walk through how we'll want our custom Hook to behave. We'll label this Hook the useQuery Hook and we'll look to declare it at the top level of a component like so:

Since the query of our application doesn't have any variables, our useQuery Hook will accept a single argument here - the GraphQL query that we'd want to make.

The Hook will return an object, where we'll be able to destruct the data from and use in our component:

Just like we've done already, we'll make our Hook accept a type variable to help type define the data being returned:

That would be all a component will need to do. The Hook will take care of tracking a state property, how the server.fetch() function is called and when it should be called (i.e when the component mounts).

useQuery Hook#

Now with an idea of what we intend to do, we'll create this Hook in a file named useQuery.ts that is to be kept in the existing src/lib/api/ folder.

In the useQuery.ts file, we'll export a function constant called useQuery that accepts a type variable labeled TData which we'll give a default value of any. The function itself will accept a query parameter argument of type string.


We've used the useState Hook before to maintain the query data kept in the component for it to be presented in the UI. We'll use the useState Hook similarly to keep track of the data to be returned from the query for us to then return at the end of our Hook.

We'll also use the useEffect Hook to help run the effect of making the API call when a component is rendered.

Let's import the useState and useEffect Hooks from React.

At the beginning of our custom Hook, we'll look to use the useState Hook to create a state object that will contain the data from our API call. Before we initialize this state property, we'll describe the shape that it expects to have in an interface called State.

The State interface will contain the data object that will be returned from our API call. The shape of data will be from a type variable the interface will accept and be passed from the useQuery Hook function. We'll label the type variable the State interface is to accept as TData as well.

Start a new discussion. All notification go to the author.