0Pricing
React Academy · Lesson

Optimistic Updates & Cache Invalidation

Update the UI instantly on mutation and invalidate cached data with tags.

Optimistic Updates & Cache Invalidation is a free React Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the React Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Welcome

In this lesson you will build mutation endpoints in RTK Query, update the UI instantly with optimistic updates, and invalidate stale cache entries using tags.

Mutation Endpoints

Define mutations with builder.mutation(). Mutations modify server data (POST, PUT, DELETE) and return a useMutation hook.
export const userApi = createApi({
  /* ... */
  endpoints: (builder) => ({
    updateUser: builder.mutation({
      query: ({ id, ...body }) => ({
        url: '/users/' + id,
        method: 'PUT',
        body,
      }),
    }),
  }),
});

Using a Mutation Hook

Destructure [trigger, result] from the mutation hook. Call trigger() with the mutation argument. result contains isLoading, isSuccess, and isError.
const [updateUser, { isLoading }] = useUpdateUserMutation();

const handleSave = async () => {
  await updateUser({ id: 1, name: 'Alice' });
};

Cache Tags for Invalidation

Tags link cached query data to mutations. Define `providesTags` on queries and `invalidatesTags` on mutations. When a mutation runs, RTK Query automatically refetches all queries that provided the invalidated tags.
endpoints: (builder) => ({
  getUsers: builder.query({
    query: () => '/users',
    providesTags: ['User'],
  }),
  deleteUser: builder.mutation({
    query: (id) => ({ url: '/users/' + id, method: 'DELETE' }),
    invalidatesTags: ['User'],
  }),
})

Granular Tag Invalidation

Use tag objects with id for fine-grained invalidation. Provide the specific user's tag on getUser and invalidate only that user's cache on updateUser.
providesTags: (result, error, id) => [{ type: 'User', id }],
invalidatesTags: (result, error, { id }) => [{ type: 'User', id }]

Optimistic Updates with onQueryStarted

Use onQueryStarted in a mutation to update the cache immediately before the server responds, then roll back if the mutation fails.
updateUser: builder.mutation({
  query: (user) => ({ url: '/users/' + user.id, method: 'PUT', body: user }),
  async onQueryStarted(user, { dispatch, queryFulfilled }) {
    const patch = dispatch(
      userApi.util.updateQueryData('getUser', user.id, draft => {
        Object.assign(draft, user);
      })
    );
    try { await queryFulfilled; }
    catch { patch.undo(); } // roll back on error
  },
})

Invalidate All Instances of a Tag Type

Using `{ type: 'User', id: 'LIST' }` as a tag for list queries lets you invalidate the full list without invalidating individual user entries.
providesTags: result =>
  result ? [
    ...result.map(({ id }) => ({ type: 'User', id })),
    { type: 'User', id: 'LIST' },
  ] : [{ type: 'User', id: 'LIST' }]

Manual Cache Invalidation

Invalidate specific tags programmatically with dispatch(api.util.invalidateTags(['User'])). Useful in event handlers that are outside components.
dispatch(userApi.util.invalidateTags(['User']));

Pessimistic vs Optimistic Updates

Optimistic: update cache before server responds (instant UI, roll back on error). Pessimistic: wait for server, then update (safer, but slower). Choose based on the mutation's failure risk.

When to Use Tags vs Manual Refetch

Use tags when you know exactly which queries to invalidate. Use refetch() from a query hook for one-off manual refreshes. Tags are more automatic and scalable for large APIs.

Quick Check

In RTK Query, what does invalidatesTags on a mutation endpoint do?

Recap

Define mutations with builder.mutation. Use providesTags on queries and invalidatesTags on mutations for auto-refetching. Use onQueryStarted with updateQueryData for optimistic updates and undo() for rollback.

Course Complete

Congratulations! You finished **Redux Toolkit & RTK Query**. You can now build Redux slices, handle async logic with createAsyncThunk, and manage server state with RTK Query caching and optimistic updates.

Frequently asked questions

Is the “Optimistic Updates & Cache Invalidation” lesson free?

Yes — the full text of “Optimistic Updates & Cache Invalidation” is free to read here on the web, and the React Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the React Academy course, upgrade to CoddyKit PRO.

What will I learn in “Optimistic Updates & Cache Invalidation”?

Update the UI instantly on mutation and invalidate cached data with tags. You practise React Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start React Academy?

No prior experience is required. React Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Optimistic Updates & Cache Invalidation” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this React Academy lesson?

Yes. Every React Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Redux Toolkit Slices & createSlice
  2. Async Logic with createAsyncThunk
  3. RTK Query: Endpoints & Auto-Caching
  4. Optimistic Updates & Cache Invalidation
← Back to React Academy