# React Query

### Installing React Query

```
npm install @tanstack/react-query@4.10.1
```

Set up a caching layer to enhance performance in `App.jsx`

```jsx
// at top
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: Infinity,
      cacheTime: Infinity,
    },
  },
});

// inside <BrowserRouter> wrapping everything inside it
<QueryClientProvider client={queryClient}>
 […]
</QueryClientProvider>
```

### Implement `useQuery`

1. Import `useQuery` from react-query.&#x20;
2. Get params with `useParams`&#x20;
3. Handle loading states.
4. Render UI based on fetched data.

```jsx
import { useParams } from "react-router-dom";
import { useQuery } from "@tanstack/react-query";
import fetchPet from "./fetchPet";

const Details = () => {
  const { id } = useParams();
  const results = useQuery(["details", id], fetchPet);

  if (results.isLoading) {
    return (
      <div className="loading-pane">
        <h2 className="loader">🌀</h2>
      </div>
    );
  }

  const pet = results.data.pets[0];

return (
    <div className="details">
      <div>
        <h1>{pet.name}</h1>
        <h2>{`${pet.animal} — ${pet.breed} — ${pet.city}, ${pet.state}`}</h2>
        <button>Adopt {pet.name}</button>
        <p>{pet.description}</p>
      </div>
    </div>
  );
};

export default Details;
```

### Implement `useQuery` for fetching breedList

1. Split fetch command into separate file called `fetchBreedList.js`&#x20;
2. Refactor `useBreedList.js` to use `useQuery`.

```jsx
async function fetchBreedList({ queryKey }) {
  const animal = queryKey[1];

  if (!animal) return [];

  const res = await fetch(
    `http://pets-v2.dev-apis.com/breeds?animal=${animal}`
  );

  if (!res.ok) {
    throw new Error(`breeds ${animal} fetch not ok`);
  }

  return res.json();
}

export default fetchBreedList;
```
