phryneas / ssr-experiments

77 stars 60 forks source link

Does the caching strategy still work on the server and do I still need to call the hooks to query data. #5

Closed browynlouis closed 1 year ago

browynlouis commented 1 year ago

Hello @phryneas first of all, thanks for the amazing work you and your team do. I see how helpful your comments are all over the web.

I'm a bit confused when it comes to using RTK query during SSR, particularly using Next.js.

I have seen in this repo that even with the use of RTK query during SSR, you still make use of the hooks to fetch for the Pokemon details in the Pokemon page.

Because of that, I have multiple questions -

Please I would really appreciate your response. Thanks @phryneas

phryneas commented 1 year ago
browynlouis commented 1 year ago

Thanks for responding at @phryneas , I still do not get the full scope, however, let me try to explain my questions in details to assist you in answering me better. Please do not mind the long text.

Starting with nextjs and SSR

I'm trying to achieve this using RTK query in getStaticProps or getServerSideProps. I want to make sure all the data needed to load a page has been generated from the server before generating the page, I don't want to rely on the hook for fetching the initial data from the server, I would only love to use the hook to get recently cached data (i.e. when the cached data has been changed using a mutation hook) and also the isFetching status.

How can I achieve this please?

phryneas commented 1 year ago

Look at the code of this repo. That's exactly what it does, in the SSR examples. It uses getServerSideProps to fetch the data on the server, seeds the cache on the client and then renders the component so the hook has immediately data available.

browynlouis commented 1 year ago

Oh.. I must have gotten confused with the use of the hook to display the Loading text, I guess the purpose of that is for the SSG page and not the SSR

Thanks @phryneas I really appreciate the help

browynlouis commented 1 year ago

Thanks @phryneas , I am closing the issue. Thanks for always helping out the devs.

browynlouis commented 1 year ago

Concerning this, even after fetching during SSR using getServideSideProps, the query hook still seems to fetch data when the page/component mounts.

I have an authMiddleware function I use to check the authentication status of a user on each request using the rtkQuery solution for SSR data fetching, and here is the content of the authMiddleware.js

export const authMiddleware = async (
  store,
  { redirectIfAuth, redirectIfNotAuth, getProps } = {}
) => {
  try {
    store.dispatch(getUser.initiate());

    const response = await Promise.all(
      store.dispatch(userApi.util.getRunningQueriesThunk())
    );

    const {
      data: { user },
    } = response[0];

    if (redirectIfAuth)
      return {
        redirect: {
          destination: redirectIfAuth,
        },
      };
    else {
      return getProps ? getProps(user) : { props: {} };
    }
  } catch (err) {
    if (redirectIfNotAuth)
      return {
        redirect: {
          destination: redirectIfNotAuth,
        },
      };

    return getProps ? getProps() : { props: {} };
  }
};

I then call the authMiddleware function inside of getServerSideProps in one of my pages, and on that same page, I call the query hook to get the supposedly already fetched data. However, even after getServerSideProps successfully runs and fetches the data, on the network tab, the query hook still seems to make a request. Also, when logging the supposedly already fetched data from the query hook, it starts as undefined, and prints the data after a moment, which verifies that the query hook still makes a request despite already fetching inside of getServerSideoProps

Here's the content of the page making the calls

const HomePage = () => {
  const { data, isError, isSuccess } = useGetUserQuery();

  return (
    <>
      <Head>
        <title>Home | Central Covers</title>
      </Head>
      <Home />
    </>
  );
};

export default HomePage;

export const getServerSideProps = wrapper.getServerSideProps(
  (store) => async (context) => {
    return await authMiddleware(store);
  }
);
phryneas commented 1 year ago

Have you set up rehydration on the client?

browynlouis commented 1 year ago

Yea I did that before now.

I just restarted my server and now it works, but unfortunately, an error relating to bad setState() comes up anytime I make use of the query hook.

I can't deduce the exact place the error must have originated from.

I looked at the stack trace and it point to the wrapper.useWrappedStore(rest) function call in my _app.js.

phryneas commented 1 year ago

I'm sorry, but at that point you'll probably have to take that up to next-redux-wrapper.

browynlouis commented 1 year ago

Alright, thanks, someone already opened up an issue concerning that, and according to the response, that's a bug that will be fixed in the upcoming version.