TanStackT
TanStack11mo ago
2 replies
worthy-azure

SSR set initialData for Tanstack Query (useQuery) isn't working

Am I doing something wrong because useQuery initialData on server is not being set from route state data resulting in a flicker of UI / hydration errors.

If I only use the state data all is good however I can't do optimistic updates via queryClient API used by useQuery/useMutation .

export const Route = createFileRoute('/')({
  component: Home,
  loader: async () => ({
    jobs: (await getJobs()) ?? [],
  }),
});

function Home() {
  const router = useRouter();
  const state = Route.useLoaderData();
  const queryClient = useQueryClient();
  const jobs = useQuery({
    queryKey: ['jobs'],
    queryFn: () => getJobs(),
    initialData: state.jobs,
  });
  
  // On server side the initial data of query is false, client side logs are all true.
  console.log('s first job enabled:', state.jobs.at(0)?.enabled); // true
  console.log('q first job enabled:', jobs.data.at(0)?.enabled); // false
  console.log('c first job enabled:', queryClient.getQueryData(['jobs'])?.at(0)?.enabled); // false

  // also have mutations that does optimistic updates use query cache
  const editJobFn = useMutation({
    mutationFn: editJob,
    onMutate: async (newJob) => {
      await queryClient.cancelQueries({ queryKey: ['jobs', newJob.data.id] });
      const previousJobs = queryClient.getQueryData(['jobs']);
      queryClient.setQueryData(['jobs'], (jobs: Jobs) =>
        jobs.map((j) => (j.id === newJob.data.id ? { ...j, ...newJob.data } : j)),
      );
      return { previousJobs };
    },
    onSettled: (job) => {
      queryClient.invalidateQueries({ queryKey: ['jobs', job?.id] });
      router.invalidate();
    },
    onError: (err, variables, context) => {
      queryClient.setQueryData(['jobs'], context?.previousJobs);
    },
  });
  
  ...
}
Was this page helpful?