Anwar Hossain
Anwar Hossain

Reputation: 301

react query calls data every time in nextjs

I used a query client inside a page component in my nextjs project where I also used getServerSideProps for server-side render. My whole page is,

const Index = ({ configData }) => {
  const { t } = useTranslation();
  const { data, isFetching } = useGetPolicyPage("/refund");
  
  return (
    <>
      <CssBaseline />
      <MetaData title={`Refund policy - ${configData?.business_name}`} />
      <MainLayout configData={configData}>
        <PolicyPage
          data={data}
          title={t("Refund Policy")}
          isFetching={isFetching}
        />
      </MainLayout>
    </>
  );
};

export default Index;
export const getServerSideProps = async () => {
  const configRes = await fetch(
    `${process.env.NEXT_PUBLIC_BASE_URL}/api/v1/config`,
    {
      method: "GET",
      headers: CustomHeader,
    }
  );

  const config = await configRes.json();
  return {
    props: {
      configData: config,
    },
  };
};

I created a custom hook for calling the react query component. The component is,

const getData = async (apiLink) => {
  const { data } = await MainApi.get(apiLink);
  return data;
};
export default function useGetPolicyPage(apiLink) {
  return useQuery("refund-policy", () => getData(apiLink), {
  
    cacheTime: 100000,
    staleTime: 100000,
  });
}

Every time when I go to the page, my refund API calls even after using cacheTime and staleTIme.

I tried to find out the way and also applied the solutions, yet, my api calls everytime.

Upvotes: 0

Views: 1071

Answers (1)

TkDodo
TkDodo

Reputation: 28938

nextJs will invoke getServerSideProps in two occasions:

  1. when you hard-load the page, it will be called and become part of the synchronous page load
  2. when you then navigate to a page, next will also invoke getServerSideProps, but with an async request.

The react-query caching is purely client side - your getServerSideProps function has no caching, so await configRes.json(); will be called every time. That's probably what you are seeing.

There are lots of discussions about this, e.g.:

and the nextJs answer is probably "Server Components". An accepted workaround is to check if the request starts with '/_next/data/ and "do nothing" in those cases:

const isServerReq = req => !req.url.startsWith('/_next');

function Post({ post }) {
  // Render post...
}

export async function getServerSideProps({ req }) {
  const initData = isServerReq(req) ? await fetch(...) : null;

  return {
    props: {
      initData,
    },
  }
}

Upvotes: 0

Related Questions