question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

QueryConfigs are not applied when prefetching in NextJS SSR

See original GitHub issue

I’m trying to prefetch some queries in App.getInitialProps (nextJS SSR). my assumption is, that even when the query is prefetched on SSR the default behaviors like refetchOnWindowFocus should be working as w/o any pre-fetching.

my _app.js

import { ReactQueryDevtools } from "react-query-devtools";
import { ReactQueryCacheProvider, makeQueryCache } from "react-query";
import { Hydrate, dehydrate } from "react-query/hydration";

import { getPosts } from "../hooks/usePosts";

const MyApp = ({ Component, pageProps }) => {
  return (
    <ReactQueryCacheProvider>
      <Hydrate state={pageProps.dehydratedState}>
        <Component {...pageProps} />
        <ReactQueryDevtools initialIsOpen position="bottom-left" />
      </Hydrate>
    </ReactQueryCacheProvider>
  );
};

MyApp.getInitialProps = async () => {
  const queryCache = makeQueryCache();
  await queryCache.prefetchQuery("posts", getPosts);

  return { pageProps: { dehydratedState: dehydrate(queryCache) } };
};

export default MyApp;

my fetcher/hook:

import { useQuery } from "react-query";
import axios from "axios";

export const getPosts = async () => {
  const { data } = await axios.get(
    "https://jsonplaceholder.typicode.com/posts"
  );
  return data;
};

export default function usePosts() {
  return useQuery("posts", getPosts);
}

I’ve created a codesandbox: https://codesandbox.io/s/distracted-pond-h45px the posts are not refetched when the window gains focus again.

Also, when trying to set some queryConfigs like staleTime, then these queryConfig is not used, devtools are still showing staleTime=0:

export default function usePosts() {
  return useQuery("posts", getPosts, { staleTime: 30 });
}

Also trying to set the staleTime as config on prefetchQuery does not work:

MyApp.getInitialProps = async () => {
  const queryCache = makeQueryCache();
  await queryCache.prefetchQuery("posts", getPosts, {staleTime: 30});

  return { pageProps: { dehydratedState: dehydrate(queryCache) } };
};

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:8

github_iconTop GitHub Comments

5reactions
alfresciancommented, Sep 7, 2020

@Ephem thanks for taking the time to clarify and pointing me to my mistake to re-create the queryCache on page change.

If anyone else is struggling with it, that’s my quick and simple solution approach if you’d like to prevent pre-fetching of queries in getInitialProps that are already in your cache (and not yet stale):

  1. some code adds the queryCache to window object, e.g. a custom Hydrate component that decorates the original one:
import React, {
  FC, useEffect,
} from 'react';
import { DehydratedState, Hydrate as ReactQueryHydrate } from 'react-query/hydration';
import { useQueryCache } from 'react-query';

interface HydrateProps {
  state: DehydratedState;
}
const Hydrate:FC<HydrateProps> = ({ state, children }) => {
  const queryCache = useQueryCache();

  useEffect(() => {
    window.__QUERY_CACHE__ = queryCache;
  }, [queryCache]);

  return <ReactQueryHydrate state={state}>{children}</ReactQueryHydrate>;
};

export default Hydrate;
  1. re-use that window.__QUERY_CACHE__ in getInitialProps when running on client side and only prefetch Queries that are not present or stale
  const queryCache = isServer ? makeQueryCache() : (window.__QUERY_CACHE__ ?? makeQueryCache());
  const cachedQueries = queryCache.getQueries()
    .filter((it) => it.state.isSuccess)
    .map((it) => it.queryKey[0]);

const prefetchQueryKeys = [myKeys].filter((key) => !cachedQueries.includes(key));

here’s an updated codesandbox: https://codesandbox.io/s/prevent-prefetch-if-cached-pkumj?file=/pages/_app.js

1reaction
Ephemcommented, Sep 4, 2020

@alfrescian The reason this is happening is that the prefetchQuery you are doing in getInitialProps is on a separate (new per route change) queryCache from the cache where the data is currently cached on the client. If you imagine this with getServerSideProps or getStaticProps that would be a bit clearer, since those are run on the server, but with getInitialProps it’s a bit trickier since it can run either on the server or on the client.

I think there are ways around this that aren’t documented right now (partly because Next.js isn’t recommending getInitialProps anymore). In getInitialProps inside of _app.js you can do some setup and pass along extra information to the getInitialProps from the pages. In there you could either use the existing queryCache if one already exists on the client, or create a new one if running on the server (or first render on client). I haven’t tried this myself with Next, but I have done the same approach in a private project that uses a very similar structure.

Since that part is working as intended and the original issue is resolved, I’ll go ahead and close this issue. Big thanks for reporting it and feel free to open new ones if you find more things! 💯

Edit: Oh and just to be clear, I’m not saying we shouldn’t have docs and/or an example for getInitialProps, a lot of people are still using it, just explaining why it wasn’t a priority. 😄 Please do share if you figure out a good way to do it!

Read more comments on GitHub >

github_iconTop Results From Across the Web

QueryConfigs are not applied when prefetching in NextJS SSR
I'm trying to prefetch some queries in App.getInitialProps (nextJS SSR). my assumption is, that even when the query is prefetched on SSR the ......
Read more >
react-query - npm
Hooks for managing, caching and syncing asynchronous and remote data in React. Latest version: 3.39.2, last published: 3 months ago.
Read more >
React Query v1.0.0 released - Morioh
Query caches are not written to memory during SSR. This is outside of the scope of React Query and easily leads to out-of-sync...
Read more >
Hooks for fetching, caching and updating asynchronous data ...
SSR Example with Next.js ... OS: Ubuntu 20; Yarn: 3.2.0; Next.js: 12.1.6 ... Gif of non-working version screencast 2022-12-13 16-16-17.
Read more >
isomorphic-relay from denvned - GithubHelp
React render not resolving the diff in server vs. client graphql response. Hi, I've got isomorphic-relay working nicely. I am finding however, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found