Fetching data with react-query

ReactQuery

📡 What you will learn

  • Fetch data over the network from the Star Wars API.
  • Display status and datas with useQuery.
  • Use an advanced React Pattern: Context API.
  • Build your own custom hook.

👾 Before we start the exercise

While many developers underestimate the complexity associated with asynchronous calls, they are a very large and complex problem (handling load state, error state, cache, refetch).

A simple, high-performance integration can be very tricky.

We are going to use TanStack Query, here is a video explaining why.

React Query is presented as a library of hooks for loading, caching, and modifying asynchronous data in React. It offers many features: a simple query with error and load status, dependent or parallel queries, and paged queries. It also includes simple and efficient cache management and ensures compatibility with server-side rendering, notably Next.js.

Here's how it works:

  1. Write your data fetching functions (here it's getDataFromApi).
  2. Wrap them in a named query with queryKey as an array of string (here it's ["dataFromApi"]).
  3. react-query handles caching, deduping, re-fetching, and loading states.
// DO NOT MONKEY COPY/PASTE ME

async function getDataFromApi() {
  const result = await fetch(`https://api.example.com/collection/`);
  const json = await result.json();
  return json;
}

function Component({ itemId }) {
  const { isLoading, isError, data } = useQuery(
    ["dataFromApi"],
    getDataFromApi
  );

  if (isLoading) {
    return <Text>Loading…</Text>;
  }
  if (isError) {
    return <Text>Something bad happened…</Text>;
  }

  return <DoStuffWithData data={data} />;
}

👨‍🚀 Exercise 2

That's the screen we will create: a list of data

Setup react-query

  • Install the library
npm install @tanstack/react-query
  • Add a QueryClientProvider and wrap the application entry point.

🔭 Hint: You can have a look at the QueryClientProvider documentation

Fetching resources across the network

In the example useQuery, isLoading and isError lives on the same files.

To have a more robust application, and separte the concerns of the data and the ui, we can wrap our queries into one custom hook useStarships().

The logic is:

  1. fetch data from the endpoint and return the result as a json
  2. Get the result from the fetch and return the result of useQuery
  3. Use our custom hook to render the UI
  • Create a new file useStarships.ts and paste the content bellow
// ./src/hooks/useStarships.ts
import { useQuery } from "@tanstack/react-query";

async function fetchData() {
  const result = await fetch(`https://swapi.py4e.com/api/starships/`);
  const json = await result.json();
  return json;
}

export function useStarships() {
  return useQuery(["starships"], fetchData);
}

Now you can write useStarships() anywhere in your Screen and React Query handles the rest.

  • Go to your Feed screen and remplace the data.json with data from the swapi.
  • Use useStarships hook to dislay a loading message.
  • Use useStarships hook to handle errors.
  • Use useStarships hook to render data with a FlatList.

If you want to display some images on your Card, you can use this placeholder https://picsum.photos/400/200 as a source.

👽 Bonus