Skip to content

Instantly share code, notes, and snippets.

@iamshubhamjangle
Created October 10, 2025 06:44
Show Gist options
  • Select an option

  • Save iamshubhamjangle/f5e91302b9690013a71afd0484c2bef3 to your computer and use it in GitHub Desktop.

Select an option

Save iamshubhamjangle/f5e91302b9690013a71afd0484c2bef3 to your computer and use it in GitHub Desktop.
react-query

Installation

npm i @tanstack/react-query
npm i -D @tanstack/eslint-plugin-query

Setup

// App.jsx
// Create a client
const queryClient = new QueryClient()

function App() {
  return (
    // Provide the client to your App
    <QueryClientProvider client={queryClient}>
      <Todos />
    </QueryClientProvider>
  )
}

Usage

GET Data

import { useQuery } from "@tanstack/react-query";
import { fetchQuestions } from "@/lib/api";

const {
  data: questions,
  isLoading,
  isError,
} = useQuery({
  queryKey: ["questions"],
  queryFn: () => fetchQuestions(),
  staleTime: 1000 * 60 * 60 * 24, // 1 day
});

POST/PUT

// hooks/useMutation.tsx
import { useMutation, useQueryClient } from "@tanstack/react-query";

/**
 * Generic mutation hook that tracks loading state by ID and invalidates queries
 * @param mutationFn - The mutation function to execute
 * @param invalidateQueryKeys - Query keys to invalidate on success
 * @returns [isMutating, mutate] - Function to check if item is mutating and mutate function
 */
function useMutationWrapper<TVariables extends { id: string }, TData = unknown>(
  mutationFn: (variables: TVariables) => Promise<TData>,
  invalidateQueryKeys: string[] = []
) {
  const queryClient = useQueryClient();

  const mutation = useMutation({
    mutationFn,
    onSuccess: () => {
      invalidateQueryKeys.forEach((key) => {
        queryClient.invalidateQueries({ queryKey: [key] });
      });
    },
  });

  /**
   * Check if a specific item is currently being mutated `mutation.variables?.id === itemId;`
   */
  const isMutating = (itemId: string): boolean => {
    return mutation.isPending && mutation.variables?.id === itemId;
  };

  return [isMutating, mutation.mutate] as const;
}

export default useMutationWrapper;

Usage Initialize the hook, returns the loading state and mutationFn Takes two params - fetchFn, invalidationKeyArray

const [isStarredMutating, mutateStarred] = useMutationWrapper<
  { id: string; starred: boolean },
  QuestionDTO
>(({ id, starred }) => toggleQuestionStarredAPI(id, starred), ["questions"]);

const onToggleStarredBtnClick = (questionId: string, currentValue: boolean) => {
  mutateStarred({ id: questionId, starred: !currentValue });
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment