It appears that React Query is not retaining cached data

After watching a tutorial on YouTube about utilizing React Query, I attempted to implement caching in my project. However, the data is fetched every time instead of being retrieved from the cache. I've reviewed my code and can't pinpoint what I'm missing. Here is the code snippet: https://codesandbox.io/s/eager-faraday-nhmlb?file=/src/App.js

Upon clicking the Planets and People buttons, I noticed that network requests are made each time I switch between them. Ideally, I would expect the data to be requested only once for each set and cached for subsequent requests.

If anyone has any insights or suggestions on what might be causing this issue, please let me know.

Answer №1

Exploring the Important Defaults section:

When using useQuery or useInfiniteQuery, cached data is automatically considered stale by default.

Stale queries are refreshed in the background under these conditions:

  • New instances of the query are mounted

Once a query's data is successfully fetched, it becomes immediately stale which leads to frequent refetching whenever the tab is changed. Adjust the staleTime (defaulted to 0) to control the refetch behavior:

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

Alternatively, you can globally set the staleTime for all queries when instantiating QueryClient like this:

const queryClient = new QueryClient({
    defaultOptions: { queries: { staleTime: 10000 }}
});

In your code, there is another issue unrelated to react-query. Here's where the problem lies:

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>
  );
}

Each time the user switches between displaying different data sources, the entire component re-renders causing a new instance of queryClient to be created and passed to QueryClientProvider, thereby resetting any client cache state. It’s recommended to refactor your components to prevent unnecessary re-rendering as shown below:

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

https://codesandbox.io/s/67040687react-query-doesnt-seem-to-be-caching-lgfej?file=/src/App.js

Answer №2

By initializing a new QueryClient within the app component, you are essentially discarding the cache every time it re-renders. To avoid this, consider creating the new QueryClient() outside of the app as shown in the provided example.

Additionally, keep in mind that even after making this adjustment, you may still observe network requests due to react-query performing background refetches with a default staleTime of 0 upon component mounting. To prevent this behavior, adjust the staleTime to a higher value if desired.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The link in the NextJs app is currently appending to the current path, but I would prefer it

Imagine the current url is: localhost:3000/foo/hello, with hello being a dynamic route. There's a Link Component with href={'/something/test'}. Upon clicking it, the goal is to land on: localhost:3000/something/test, where test is another dy ...

This particular kind of mistake arises: "sharp" module not detected

Error: The module 'sharp' could not be found. The required stack includes: - D:\Marketing\sbj-react\suburban\node_modules\gatsby-plugin-manifest\safe-sharp.js - D:\Marketing\sbj-react\suburban&bs ...

Creating a multidimensional array in React JS and rendering it on the screen

Is there a way to showcase the array of cards in two columns instead of one, with images displaying sequentially? return ( <div> { data?.length > 0 && data?.map(item=>{ return( ...

Issues arising with code splitting using React HashRouter in a project utilizing Typescript, React 17, and Webpack 5

Encountered build issues while setting up a new project with additional dependencies. package.json: { "name": "my-files", "version": "1.0.0", "description": "App", "main": " ...

Experiment with implementing a fresh validation protocol within reactjs material

I attempted to implement a new validation rule using react-material 1.0 Below is the code I used to add the new rule, but encountered an error ValidatorForm.addValidationRule('isCanRequired', (value) => { if(this.state.canSameAccount ...

Can React Native support styling using server-side data?

One of my React Native (RN) components is rendering data from an external server. The data is enclosed within RN components. For example: ... <View> <Text>{this.props.db.greeting}</Text> </View> The 'DB' object is si ...

The sequence of execution in React hooks with Typescript

I'm having difficulty implementing a language switching feature. On the home page of my app located at /, it should retrieve a previously set preference from localStorage called 'preferredLanguage'. If no preference is found, it should defau ...

Discover the key technique to modify the status of a different component in React

I'm working on developing a popup window component. Here is the initial code for the popup component: The component takes in two props, activity (which can be set to true or false) and content (a view component that will be displayed inside the popu ...

What steps do I need to follow to deploy my React application on GitHub?

After successfully creating my React project and pushing the full repository to GitHub through Visual Studio Code, I am now wondering how I can deploy my React project live on a server using the tools available on GitHub. Can anyone provide guidance on t ...

Utilizing Multer for MERN File Upload

For my project, I am working on creating a Pinterest-like platform where users can upload images. However, I am facing an issue with fetching files from the frontend to the backend using axios. Below is the code for the server: After testing various solut ...

What is the process for transferring a function to reducers in Redux Toolkit?

In one of my files called Main.tsx, I have a function that sends a request and retrieves data: async function fetchProducts(productsPage = 1, id?: number) { const itemsPerPage = 5 let url: string if (id) { url = `https://reqres.in/api/ ...

Encountering a Hydration Error in Next.JS with Sanity integration when adding a Time Stamp

Does anyone have a solution for this issue? I keep getting a hydration error whenever I try to include a timestamp fetched from Sanity. This is how it appears on the page: <p className="font-extralight text-sm"> Post by <span c ...

What is the best way to declare a variable while rendering HTML in a ReactJS loop?

render() { return ( <ul> {scopeOptions.map((option, keyOption) => ( const myVar = keyOptions * 5 <li key={keyOption}> <a href="#" data-value={option.value}>{option.label}</a> </li> ))} </ul> ) } I ...

Prevent the collapse functionality in a Material-UI Stepper component

Currently in the development phase of a React website using Material-UI, with a focus on incorporating the Stepper component. Is there a method available to prevent the collapse and expansion of each individual StepContent in a vertical Stepper? The goal ...

Creating a dynamic nested menu using React and JSON data

Creating a sidebar menu using data from a .json file, where the menu items are different BMW models. An example dataset is provided below: Here's my output: <List> {Menuhandler( menuDataHandler(JsonSeries) )} </List> The MenuDataHa ...

Instructions on how to eliminate the minutes button from Material UI datetime picker

I'm currently working on customizing a datetimepicker from materialUI in ReactJS. My goal is to prevent the user from seeing or selecting minutes in the picker interface. Despite setting the views prop to include only year, month, date, and hours, use ...

The main-panel div's width increase is causing the pages to extend beyond the window's width limit

I recently downloaded a Reactbootstrap theme and managed to integrate it with NextJS successfully. However, I am facing an issue where my <div className="main-panel"> in the Layout.js is extending slightly beyond the window. It seems like t ...

Difficulty encountered when transferring data between React frontend and Node Express backend (CORS and API endpoints)

Encountering an issue where submitting form data results in a 404 error stating the endpoint is not found. The server.js file can be reviewed for further details on how to set up sending an email from the node express server upon passing data through the b ...

I attempted to post a collection of strings in ReactJS, only to receive a single string response from the Web

I was troubleshooting an issue where only one string from ReactJS was being sent to WebApi instead of an array of strings. Below is the ReactJS code snippet I used: import React, { useState } from "react"; import axios from "axios"; e ...

When attempting to call a bundle file using browserify from React, an unexpected character '�' Syntax error is thrown: react_app_testing/src/HashBundle.js: Unexpected character '�' (1:0

Hey there, I'm currently struggling with an unexpected unicode character issue. Let me provide some context: I've created a simple class called HashFunction.js that hashes a string: var crypto = require('crypto') module.exports=class H ...