Skip to content

broadcastQueryClient doesn't keep cache between tabs #2142

@DoneDeal0

Description

@DoneDeal0

Describe the bug
I'm trying broadcastQueryClient feature to make the cache persist across tabs. When opening a new tab, the server endpoint is called, while react-query should prevent this and return the cache data instead.

My usecase:
When the app mounts, I make an api call to retrieve the user's info and store them in a global state. There are sensitive informations, so local-storage is not an option. I have a search result page. Users open a new tab each time they click on a product. Each new tab remounts the whole app, and the /get-user-infos route is called repeatedly. I need to cache the result across tabs.

To Reproduce
index.js

import { QueryClient, QueryClientProvider } from "react-query";
import { broadcastQueryClient } from "react-query/broadcastQueryClient-experimental";

const queryClient = new QueryClient();
broadcastQueryClient({
  queryClient,
  broadcastChannel: "myapp",
});

ReactDOM.render(
  <QueryClientProvider client={queryClient}>
    <App />
  </QueryClientProvider>,
  document.getElementById("root")
);

App.js

export default function App() {
  const { user, loading } = getUserInfos();
  return (
    <BrowserRouter>
      {loading ? "loading..." : <div>hello {user.name}! </div>}
      <Switch>
        <Route to="/" render={Home} />
        <Route to="/user" render={User} />
      </Switch>
    </BrowserRouter>
  );
}

service.js (where the api cal is made)

/* eslint-disable react-hooks/rules-of-hooks */
import { useQuery } from "react-query";
import { api } from "./config";

const _getUserInfos = async () => {
  try {
    const res = api.get("/get-user-infos");
    return res;
  } catch (err) {
    return err;
  }
};

export const getUserInfos = () => {
  const { data, isLoading } = useQuery("contact", () => _getUserInfos(), {
    staleTime: 1000 * 60 * 60 * 24, // 24 hours
    cacheTime: 1000 * 60 * 60 * 24, // 24 hours
  });
  return { user: data && data.data.user, loading: isLoading };
};

The new tab is open like this on <Home/>

  const onOpen = () => {
    const tab = window.open("/user");
    tab.focus();
  };

The cache works fine as long as I use react-router-dom on the same page.

The server:

const app = require("express")();
const cors = require("cors");

app.use(cors({ credentials: true, origin: ["http://localhost:3000"] }));

app.listen(8000, () => console.log(`server is listening on port 8000!`));

app.get("/get-user-infos", (req, res) => {
  console.log("login route called!");
  res.status(200).json({
    user: {
      name: "joe",
      _id: "1234",
    },
  });
});

Expected behavior
React-query returns the cache for /get-user-infos when opening a new tab.

Desktop (please complete the following information):

  • OS: osx
  • Browser: chrome

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions