Table of contents
One of my favourite library in React ecosystem is React-Query. If you don't know about it already, React-Query helps you to fetch, cache and manage server state in your react application. It is fully customizable and requires zero-configuration out of the box.
useQuery hook
One of the most useful hook that React-Query Provides is useQuery which is used to fetch data from server. It takes key( unique key for the query ), resolver( function that returns a promise ) and config object ( configuration object using which the query can be customized ), and returns an object containing bunch of useful properties like query state, data, error etc.
import { useQuery } from 'react-query';
export default function Post({ id }) {
const { status, data, error } = useQuery("post", () => axios.get(`/some-post/${id}`), { staleTime: Infinity } );
}
In the above code, we can observe that :
- 1st argument is
"post"
which is a unique key for this query - 2nd argument is function that returns promise. Here, we're using axios to return promise
- 3rd argument is config object where we've set the stale time to infinity for our cache
Dependent Queries
As the name suggests, Dependent queries are dependent on some condition and wouldn't run automatically ( like on component mount ) unless the condition is met. To make a query dependent, we just need to pass a boolean flagenable
in the config object.
import { useQuery } from 'react-query';
export default function Post({ id }) {
const { status, data, error } =
useQuery("post",
() => axios.get(`/some-post/${id}`),
{
enable: false,
staleTime: Infinity
}
);
}
There are many scenarios where we would need a query like this. For example, suppose we want to fetch and show specific post in the modal only when user clicks on that particular post from array of posts. So in this case, our query is dependent on post id
and hence, we can pass enable: !!id
in config object to make it dependent query.
import { useQuery } from 'react-query';
export default function Post({ id }) {
const { status, data, error } =
useQuery("post",
() => axios.get(`/some-post/${id}`),
{
enable: !!id,
staleTime: Infinity
}
);
}
Invalidate Cache of Dependent Queries
But the things get tricky when you try to invalidate the cache of dependent queries because these queries will ignore query client invalidateQueries
and refetchQueries
calls that would normally result in the query refetching.
So to invalidate the cache, you need to manually refetch the query using refetch
method that useQuery
hook returns.
// inside the component
const { refetch } =
useQuery("post",
() => axios.get(`/some-post/${id}`),
{
enable: !!id,
staleTime: Infinity
}
);
// calling refetch whenever user clicks on button to refetch the post
const handleFetchPostOnClick = () => refetch()
}
And that's how you can invalidate the cache of dependent queries.
Bonus tip : You can also provide complex key like ["post", id]
which will fetch the query everytime id
changes
import { useQuery } from 'react-query';
export default function Post({ id }) {
const { status, data, error, refetch } =
useQuery(["post", id],
() => axios.get(`/some-post/${id}`),
{
enable: !!id,
staleTime: Infinity
}
);
}
Thanks for reading.