Home > Net >  React Query invalidateQueries not updating the UI
React Query invalidateQueries not updating the UI

Time:01-15

My UI is not updating on the creation of a project with invalidateQueries. I have confirmed that the database updates are being made successfully and the onSuccess functions are being called. I'm unsure what I am doing wrong, and would love some help.

useProjects.ts

import { getProjects } from 'queries/get-projects';
import { useQuery } from 'react-query';

function useGetProjectsQuery() {
  return useQuery('projects', async () => {
    return getProjects().then((result) => result.data);
  });
}

export default useGetProjectsQuery;

get-project.ts

import { supabase } from '../utils/supabase-client';

export const getProjects = async () => {
  return supabase.from('projects').select(`*`);
};

useCreateProject.ts

import { useUser } from '@/utils/useUser';
import { createProject } from 'queries/create-project';
import { useMutation, useQueryClient } from 'react-query';

export const useCreateProject = () => {
  const { user } = useUser();
  const queryClient = useQueryClient();

  return useMutation(
    ({ title, type, bgColorClass, pinned }: any) => {
      return createProject(title, type, bgColorClass, pinned, user.id).then(
        (result) => result.data
      );
    },
    {
      onSuccess: () => {
        queryClient.invalidateQueries('projects');
      }
    }
  );
};

create-project.ts

import { supabase } from '../utils/supabase-client';

export async function createProject(
  title: string,
  type: string,
  bgColorClass: string,
  pinned: boolean,
  userId: string
) {
  return supabase
    .from('projects')
    .insert([
      { title, type, bg_color_class: bgColorClass, pinned, user_id: userId }
    ]);
}

Home Component

const { data: projects, isLoading, isError } = useGetProjectsQuery();
const createProject = useCreateProject();

const createNewProject = async () => {
    await createProject.mutateAsync({
      title: projectName,
      type: selectedType.name,
      bgColorClass: _.sample(projectColors),
      pinned: false
    });
  };

_app.tsx

  export default function MyApp({ Component, pageProps }: AppProps) {
 const [initialContext, setInitialContext] = useState();
 const [supabaseClient] = useState(() =>
   createBrowserSupabaseClient<Database>()
 );
 useEffect(() => {
   document.body.classList?.remove('loading');
 }, []);

 const getUserDetails = async () =>
   supabaseClient.from('users').select('*').single();
 const getSubscription = async () =>
   supabaseClient
     .from('subscriptions')
     .select('*, prices(*, products(*))')
     .in('status', ['trialing', 'active'])
     .single();

 const getInitialData = async () => {
   const userDetails = await getUserDetails();
   const subscription = await getSubscription();
   setInitialContext({
     //@ts-ignore
     userDetails: userDetails.data,
     subscription: subscription.data
   });
 };

 const queryClient = new QueryClient({
   defaultOptions: {
     queries: {
       retry: 0
     }
   }
 });

 useEffect(() => {
   getInitialData();
 }, []);

 return (
   <QueryClientProvider client={queryClient}>
     <SessionContextProvider supabaseClient={supabaseClient}>
       <MyUserContextProvider initial={initialContext}>
         <SidebarProvider>
           <Component {...pageProps} />
           <ReactQueryDevtools initialIsOpen={false} />
         </SidebarProvider>
       </MyUserContextProvider>
     </SessionContextProvider>
   </QueryClientProvider>
 );
}

I have tried moving the onSuccess followup calls to the Home component, and within the hooks, neither one updates the UI. I'm unsure what I am doing wrong and the react query devtools is not helpful.

CodePudding user response:

You are instantiating QueryClient on every render pass so the cache of query keys is being torn down and rebuilt often.

Instantiate this outside of render:

const queryClient = new QueryClient({
   defaultOptions: {
     queries: {
       retry: 0
     }
   }
});

export default function MyApp({ Component, pageProps }: AppProps) {
 const [initialContext, setInitialContext] = useState();
 // ... etc

This will ensure the client is always stable.

  • Related