# React Query from Beginner to Advanced

> A practical guide to mastering CRUD mutations in React Query, covering optimistic updates, cache management, invalidation strategies, and the latest improvements in TanStack Query v5.

Source: https://zop.dev/resources/blogs/react-query-from-beginner-to-advanced
Published: 2025-11-27 · Author: gursewak-singh · Tags: cache-invalidation, crud-mutations, frontend-performance, optimistic-updates, react-query, tanstack-query, usemutation

---

## Main Takeaway
Mastering React Query for all CRUD mutations (Create, Read, Update, Delete) transforms your app development process by enabling smooth, real-time UI updates and robust cache management. This guide will walk through React Query's mutation handling, including beginner-friendly explanations and advanced tips for cache optimization, error management, and user experience.

---

## 1. What is React Query? Why Use It Over Traditional Fetching?

React Query (now officially called TanStack Query) is a powerful library for managing remote data (e.g., from REST APIs) in React applications.

Instead of writing manual fetching logic and state management, React Query provides hooks like:

- **useQuery** (for reading/fetching data)
- **useMutation** (for creating, updating, or deleting data)

### Key Benefits

- **Automatic Caching:** Caches fetched data, reducing redundant requests.
- **Background Sync:** Keeps data fresh behind the scenes.
- **Smart Updates:** Reduces UI glitches and stale displays.
- **Error/Loading Management:** Handles loading, success, error, and refetch states with minimal code.

---

## 2. Core Concepts: Query vs. Mutation

- **useQuery:** For fetching and caching data (the "read" in CRUD).
- **useMutation:** For making changes—creating (POST), updating (PUT/PATCH), or deleting (DELETE) data.
  - Mutations are not cached automatically, but are essential for UI side-effects and cache synchronization after data changes.

---

## 3. CRUD Mutations: The Universal Workflow

React Query handles all write operations (POST, PUT/PATCH, DELETE) through the `useMutation` hook.

[Here’s the standard mutation flow suitable for any CRUD action](https://tkdodo.eu/blog/mastering-mutations-in-react-query)

```
import { useMutation, useQueryClient } from '@tanstack/react-query';

const updateItem = async ({ id, fields }) => {
  const response = await fetch(`/api/items/${id}`, {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(fields),
  });
  if (!response.ok) throw new Error('Error updating item');
  return response.json();
};

function UpdateItemComponent() {
  const queryClient = useQueryClient();
  const mutation = useMutation({
    mutationFn: updateItem,
    onMutate: async (variables) => {
      await queryClient.cancelQueries({ queryKey: ['items'] });
      const previousItems = queryClient.getQueryData(['items']);
      // Make an optimistic update here
      // Modify or remove the updated item as needed
      queryClient.setQueryData(['items'], (old) => { ... });
      return { previousItems };
    },
    onError: (err, variables, context) => {
      queryClient.setQueryData(['items'], context.previousItems);
    },
    onSuccess: (data, variables, context) => {
      queryClient.setQueryData(['items'], (old) => { ... }); // Insert server response
      // Or simply invalidate for a refetch
      queryClient.invalidateQueries({ queryKey: ['items'] });
    },
    onSettled: () => {
      // Final cleanup; usually triggers a refetch just in case
    },
  });
}
```

---

## 4. Optimizing for UI Speed: Optimistic Updates

Optimistic updates let the UI reflect changes *before* the server responds — giving instant feedback.

### Steps:

- **Cancel Queries:** Pauses background fetching.
- **Snapshot:** Save current cached data for rollback.
- **Optimistic Change:** Update the cache immediately.
- **Rollback on Error:** Restore using the snapshot.
- **Server Sync:** Apply real server response or refetch.

---

## 5. Mutation Strategies: When to Invalidate, When to Update Directly?

&nbsp;

| Action | Direct Cache Update | Invalidate & Refetch |
|--------|----------------------|------------------------|
| **When?** | You have the new data | Change affects many places |
| **Benefit** | Instant UI, fewer network calls | Guaranteed consistency |
| **Downside** | Can go stale if backend changed | Extra API calls, visible refresh |

### Strategy Notes

- **Direct Update (`setQueryData`)** → fast, isolated updates
- **Invalidate (`invalidateQueries`)** → best for global/complex updates

---

## 6. Optimistic Update Patterns for CRUD

&nbsp;

| Operation | Optimistic (onMutate) | Server Sync (onSuccess) |
|-----------|------------------------|---------------------------|
| **POST** | Add item with temp ID | Replace temp ID or refetch |
| **PUT/PATCH** | Replace item in cache | Update with server response / refetch |
| **DELETE** | Remove item from cache | Invalidate affected queries |

---

## 7. Best Practices for CRUD with React Query

- **Use stable query keys** for precise updates.
- **Centralize logic with custom hooks** (e.g., `useUpdateItem`).
- **Always implement rollbacks** for optimistic updates.
- **Avoid redundant invalidation** when cache updates already reflect state.
- **Handle dependent queries** when multiple screens rely on the same data.
- **Use granular invalidation** where possible.

---

## 8. Advanced: What's New in TanStack Query v5?

- **Cleaner API:** Single options object for all hooks.
- **Optimistic Updates Simplified:** More elegant mutation workflow.
- **Enhanced DevTools:** Better visibility into query/mutation states.
- **Improved TypeScript Support:** Safer, more predictable types.

---

## 9. Conclusion

By applying these strategies—`onMutate` for optimism, `onError` for rollback, `onSuccess`/`onSettled` for cache management—developers can build high-performance React apps with instant UI feedback and strong data consistency.

Whether you're beginning or optimizing a large app, React Query helps you focus on *experience*, not boilerplate.

---
