I'm trying out react-query and want to see it caching. I have a page that gets a list of Books.
Note, some code obviously left out for brevity just trying to show the important parts.
const useBooks = options => {
return useQuery(['books', options], bookApi.fetchBooks(options));
}
const Books = () => {
useEffect(() => () => console.log("unmount"), []);
const [options, setOptions] = useState({}); // options ex: { page: 1, search: "test"}
const {error, isLoading, data} = useBooks(options);
return books.map(book => <div>{book.name}</div>;
}
Now this Books is a "page" in my app using react-router-dom:
const App = () => {
return (
<Router>
<>
<Route exact path="/">
<Home />
</Route>
<Route path="/books">
<Books />
</Route>
</>
</Router>
)
}
When I go back and forth between "Home" and "Books" (by clicking Nav links in my app) I see the books fetch hitting the network every time. I also see "unmount" in the console.
I originally had the Routes wrapped in a Switch, and removed this but the Books component still appears to unmount. I am hoping it will not unmount and I will not see the network fetch, and the books will be pulled from the react-query cache. I also tried making the useBooks hook not use the search options param but the results were the same.
How do I use avoid the network fetch in my scenario?
React Query is a library that has 2 simple hooks which provide fetching, caching and updating asynchronous data in React applications. It was created by open sourcerer Tanner Linsley in 2019, and now it is proven that it is very useful in server state management in React applications.
The QueryCache is the storage mechanism for React Query. It stores all the data, meta information and state of queries it contains. Normally, you will not interact with the QueryCache directly and instead use the QueryClient for a specific cache.
So if you are building a simple application and want a ready-to-go simple solution then SWR should be your choice. But if you need more control and customization and want to get the most out of the developer tools then definitely go for react-query.
Get a single Query String value location.search object: import React from 'react'; import { useSearchParams } from 'react-router-dom'; const Users = () => { const [searchParams] = useSearchParams(); console. log(searchParams); // ▶ URLSearchParams {} return <div>Users</div>; };
react-router
will unmount your component when you navigate away from it, yes. But that is on purpose and not the problem.
When a component that uses a react-query hook mounts, it will trigger a fetch (because of mounting). However, if you already have data in the cache for this specific key, you will instantly get that data returned as "stale data", and the fetch will happen in the background only.
If you want to avoid the request going out, you can either:
refetchOnmount
to false
so that there will be no refetch when the component mountsstaleTime
on your queryI would suggest setting the staleTime
: It will tell react-query for how long the data should be considered "fresh". If you set it to 5 minutes, there will be no background-refetch for 5 minutes - the data will always come from the cache directly. staleTime
defaults to 0
, so you will always get background refetches.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With