Initial Query Data in React Query
Tags: javascript, beginners, react, webdev
Published: 2022-10-02 11:14:50

Another way we can improve the data fetching/viewing experience of the user is by providing Initial Query Data in config options to the `useQuery` hook. Let us first consider why we need it in the first place.

We know when we hit `/companies` endpoint we get a list of companies where each company looks like:

```jsx
{
	"id": 1,
	"name": "Microsoft",
    "ceo": "Satya Nadela"
}
```

Now consider another `/companyDetails` endpoint that fetches the details of the company with companies looking as:

```jsx
{
	"id": 1,
	"name": "Microsoft",
	"ceo": "Satya Nadela",
	"founder": "Bill Gates",
	"headQuarters": "Redmond, Washington, United States"
}
```

Note that some data like `name`, `id`, and `ceo` is common between the above 2 company objects.

Now let us use `useQuery` hook to fetch the company details using `/companyDetails` endpoint

```jsx
const fetchCompanyDetails = ({ queryKey }) => {
  const id = queryKey[1];
  return fetch(`http://localhost:4000/companyDetails/${id}`).then((response) =>
    response.json()
  );
};

const { 
	isLoading, 
	data: companyDetails 
} = useQuery(["company-details", id], fetchCompanyDetails);
```

*Note: For testing purposes, I have set the network throttling to Slow 3G in the network tab of Chrome Devtools.*

![why we need initialQUeryData](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/glmp2q3aas574rghe3lf.gif)

From the above, we can note that each time the user clicks on the company name the loading state is shown and then complete company details are then displayed to the user.
This is where `intialData` can help. It prevents the loading state to be shown to the user by showing the user, already cached information thereby thus improving the overall data fetching/viewing experience.

Now that we know why we need initial query data let us see how to use it.

```jsx
import React from "react";
import { useParams } from "react-router-dom";
import { useQuery, useQueryClient } from "@tanstack/react-query";

const fetchCompanyDetails = ({ queryKey }) => {
  const id = queryKey[1];
  return fetch(`http://localhost:4000/companyDetails/${id}`).then((response) =>
    response.json()
  );
};

const Company = () => {
  const { id } = useParams();
  const queryClient = useQueryClient();

  const {
    isLoading,
    data: companyData,
  } = useQuery(["company-details", id], fetchCompanyDetails, {
    initialData: () => {
      const cachedCompanyData = queryClient
        .getQueryData("companies")
        .find((cachedCompany) => cachedCompany.id === parseInt(id));
      console.log({ cachedCompanyData });
      return cachedCompanyData ? cachedCompanyData : undefined;
    },
  });

  if (isLoading) {
    return <h1>loading</h1>;
  }

  return (
    <div>
      <h2>name: {companyData.name}</h2>
      <h2>ceo: {companyData.ceo}</h2>
      <h2>founder: {companyData.founder}</h2>
      <h2>headquarters: {companyData.headQuarters}</h2>
    </div>
  );
};

export default Company;
```

We can provide `initialData` config to the useQuery hook which is a function, whatever we return from this function will serve as the initial data for the page but if we return `undefined` then react query sets our app in a hard loading state until the complete data is fetched thus preventing from errors.

In our case since we already have some data to be shown to the user, we get that data from the cache using `queryClient.getQueryData("companies")` this returns a list of companies in which we perform a search operation to find the clicked company using the `id` which is accessible using `useParams` hook if in case the cache is empty then we return `undefined` else we return the cached company data. Here’s what the result looks like

![initialQueryData usage](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g97rvfhc0ja5ghw28bt9.gif)


Notice how the loading state is not shown this time and the user is shown the cached information while the data is being fetched in the background and shown once done as if it is being fetched on the go.

---

## Thank you for reading!

In the next lesson, we will tackle one of the most common UI pattern problem that every Frontend Developer has faced which is performing paginated and infinite queries.
We'll see how easy React Query makes it for us to perform such operations.

Feel free to reach out to me! 😊

[💻 Github](https://github.com/nischaldutt) [✨ Twitter](https://twitter.com/nischal_dutt) [💌 Email](mailto:nischaldutt01@gmail.com) [💡Linkedin](https://www.linkedin.com/in/nischal-dutt) 

Till then happy coding!