Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Query doesn't seem to be caching

I was following an example I saw on YouTube for using React Query, but I can't seem to get the caching to work as expected. In my app the data is fetched every time. Not sure if I'm missing something obvious. Here is my code: https://codesandbox.io/s/eager-faraday-nhmlb?file=/src/App.js

When clicking the Planets and People buttons, I can see network requests being made each time I flip back and forth. I would expect to see it make a request for each set of data once at least for some time while the cache is still active.

Anyone know what might be wrong?

like image 731
wy125 Avatar asked Apr 11 '21 01:04

wy125


People also ask

Does React query cache?

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.

Where does React query store cache?

react-query stores the cache in-memory. If you want to additionally sync the storage somewhere else, have a look at the persistQueryClient plugin.

Is React query any good?

React-Query — The good partsIt provides valuable tools to improve reliability of server data (invalidating data and marking data as stale). It provides Tools to improve fetch UX (prefetching, re-fetching, caching, and more).

What is query cache in React query?

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.


2 Answers

From Importaint Defaults section:

Query instances via useQuery or useInfiniteQuery by default consider cached data as stale.

Stale queries are refetched automatically in the background when:

  • New instances of the query mount

By default, when a query is successfully fetched, it's considered stale immediately, that's why your data is refetched every time you change the tab. You can set a longer staleTime (default to 0) if you don't want the aggressive refetching behavior:

const { isLoading, error, data } = useQuery("planets", fetchPlanets, {
  staleTime: 10000, // only eligible to refetch after 10 seconds
});

There is another error in your code not very related to react-query, in this code of yours below:

function App() {
  const [page, setPage] = useState("planets");

  const queryClient = new QueryClient();

  const pageSetter = (page) => {
    setPage(page);
  };

  return (
    <QueryClientProvider client={queryClient}>
      <div className="App">
        <h1>Star Wars Info</h1>
        <Navbar setPage={pageSetter} />
        <div className="content">
          {page === "planets" ? <Planets /> : <People />}
        </div>
      </div>
    </QueryClientProvider>
  );
}

Every time the user clicks the buttons to display different data, the whole component gets re-render, a new instance of queryClient is created and passed to QueryClientProvider, resetting any internal state of the client cache. You should decouple your component to avoid unnecessary re-render like this:

function Content() {
  const [page, setPage] = useState("planets");
  const pageSetter = (page) => {
    setPage(page);
  };

  return (
    <div className="App">
      <h1>Star Wars Info</h1>
      <Navbar setPage={pageSetter} />
      <div className="content">
        {page === "planets" ? <Planets /> : <People />}
      </div>
    </div>
  );
}

// top level component, should not get re-rendered
function App() {
  const queryClient = new QueryClient();

  return (
    <QueryClientProvider client={queryClient}>
      <Content />
    </QueryClientProvider>
  );
}

Live Demo

Edit 67040687/react-query-doesnt-seem-to-be-caching

like image 135
NearHuscarl Avatar answered Sep 19 '22 16:09

NearHuscarl


You are creating a new QueryClient inside the app component, so when it re-renders, you basically throw away the cache. Create the new QueryClient () outside of the app like in the example.

Also, please note that you will then still see network requests, because react-query will do background refetches with the default staleTime of 0 when a component mounts. You can set it to something higher if you don’t want that.

like image 23
TkDodo Avatar answered Sep 23 '22 16:09

TkDodo