DEV Community

Cover image for Using React Query with TypeScript
Olabisi Olaoye
Olabisi Olaoye

Posted on

Using React Query with TypeScript

When retrieving data from an API (application programming interface) in React, it's always important to do so in the most suitable way for your application. But because there's more than one way to do it, it proves to be problematic. (Throw in TypeScript and it gets even more complicated.) Many developers have acquainted themselves with React Query, a library that simplifies data fetching and state management.

More Resources

Using TypeScript with React Query takes the developer experience further by ensuring that the request and response from the API is properly defined. Plus, it saves you from unprecedented runtime errors that JavaScript may not notice. Let's try fetching some data from an online fake API.

First, we install the React Query package (for data fetching) and the Axios package (for making HTTP requests).

npm i @tanstack/react-query axios
Enter fullscreen mode Exit fullscreen mode

Say we want to get all posts from the API. That means we are making a GET request. When we look at the response, it's an array of objects like this:

[
  {
    "userId": 1,
    "id": 1,
    "title": "Mary had a little lamb",
    "body": "Mary had a little lamb whose fleece was white as snow."
  },
  ...
]
Enter fullscreen mode Exit fullscreen mode

From this data, we can create an TypeScript interface to infer what type of data we're looking to receive. It'll look something like this:

interface Posts {
  userId: number;
  id: number;
  title: string;
  body: string;
}
Enter fullscreen mode Exit fullscreen mode

In our component, we create an asynchronous function to make the request. Asynchronous functions always return a Promise, but we will take advantage of TypeScript by infering the Posts[] type on the Promise. This ensures that TypeScript knows what kind of data we're going to get.

const getPosts = async (): Promise<Posts[]> => {
  const posts = await axios.get('https://jsonplaceholder.typicode.com/posts')?.data;
  return posts;
}

Enter fullscreen mode Exit fullscreen mode

Now we can make proper use of React Query by using the useQuery hook.

const {data, isLoading, isError} = useQuery({
  queryKey: ['get-posts'],
  queryFn: getPosts
})
Enter fullscreen mode Exit fullscreen mode

Note that we destructured the hook into an object with the properties above.

  • data represents the response from the API call.
  • isLoading is a boolean value which is true when there is no ongoing query attempt.
  • isError is a boolean value which is true when there was an error fetching the query.

There are many more properties we can use for different functions, but we'll stick with these three for this example.

Given the isLoading and isError properties, we can decide what to render to the browser at each state of the data fetching process. Here's what the whole code looks like:

export default function Posts() {
  const getPosts = async (): Promise<Posts[]> => {
    const posts = await axios.get('https://jsonplaceholder.typicode.com/posts')?.data;
    return posts;
  }
  const {data, isLoading, isError} = useQuery({
    queryKey: ['get-posts'],
    queryFn: getPosts
  })

  if (isLoading) {
    return <div>Loading posts...</div>
  }

  if (isError) {
    return <div>Oops!</div>
  }

  return (
    <div>
    {data?.map((post) => (
      <p key={post.id}>{post.body}</p>
    ))}
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

It's important to note that when familiarizing yourself with a library, the documentation is the best place to begin. There you can discover more techniques to solving a problem and how to apply them in different use cases.

Top comments (0)