#deserialized data is correct, stale data still shows. how do you properly overwrite cache from RSC?

3 messages · Page 1 of 1 (latest)

scarlet sun
#

I have a pretty straightforward setup here. In a server component I have

import { api, HydrateClient } from "~/trpc/server";

export default async function Posts() {
  await api.posts.getPosts.prefetch();
  return (
    <HydrateClient>
      <ClientComponent />
    </HydrateClient>
  );
}

In the client component:

import { api } from "~/trpc/react";

export function ClientComponent() {
  const [data] = api.posts.getPosts.useSuspenseQuery();

  return ...
}

Now in this client component you can click a button to edit a post, which takes you to a simple edit post page. The hook I use for editing the post looks like this:

export function useEditPost() {
  const router = useRouter();
  const utils = api.useUtils();

  return api.posts.editPost.useMutation({
    onMutate: () => {
      utils.posts.getPosts.cancel();
    },
    onSuccess: async () => {
      toast.success("Post updated");
      router.push("/posts");
    },
  });
}

No here's where I'm having difficulty. The onSuccess routes the user back to the posts page. The posts page hits the RSC, which correctly gets the freshest data (with the edited posts details), but for a brief moment the ClientComponent still shows the old values.

Simply put, I want values from the RSC to always override any previously cached values.

My workaround for now is to call removeQueries on getPosts, which feels okay since I'm removing the query right before heading to the RSC which will hydrate it, but I'm not sure this is the right pattern - @main snow seems to encourage not using removeQueries. Any ideas on how to move forward here? Am I missing something?

scarlet sun
#

One approach is to go the initialData route and pass in the initialData from the RSC, then in the client component do

const { data } = api.posts.getPosts.useQuery(undefined, {
  gcTime: 0,
  initialData,
});

but I'd love to use the prefetching pattern if possible / really understand what it is I'm seeing here and how others deal with the issue.

#

Simply put, I want data fetched in an RSC to always replace existing cache data, / I'm unsure why this doesn't happen by default? Genuinely curious here - am I doing something special / out of the ordinary?