Lesson 11 / 25

Caching, Tags and Invalidation

Refetch the right data after a change.

providesTags and invalidatesTags

Cached results are kept while components subscribe to them and for keepUnusedDataFor seconds afterwards (60 by default). To keep data fresh after mutations, declare tagTypes on the API, let queries provide tags such as { type: 'Post', id } and a list tag { type: 'Post', id: 'LIST' }, and let mutations invalidate them. When a mutation succeeds, every subscribed query that provided a matching tag refetches automatically.

Tagging posts

Queries provide, mutations invalidate.

export const api = createApi({
  reducerPath: 'api',
  baseQuery: fetchBaseQuery({ baseUrl: '/api' }),
  tagTypes: ['Post'],
  endpoints: (builder) => ({
    getPosts: builder.query<Post[], void>({
      query: () => 'posts',
      providesTags: (result = []) => [
        ...result.map(({ id }) => ({ type: 'Post' as const, id })),
        { type: 'Post' as const, id: 'LIST' },
      ],
    }),
    addPost: builder.mutation<Post, Omit<Post, 'id'>>({
      query: (body) => ({ url: 'posts', method: 'POST', body }),
      invalidatesTags: [{ type: 'Post', id: 'LIST' }],
    }),
    updatePost: builder.mutation<Post, Post>({
      query: ({ id, ...body }) => ({ url: `posts/${id}`, method: 'PATCH', body }),
      invalidatesTags: (_res, _err, { id }) => [{ type: 'Post', id }],
    }),
  }),
});

Labels on storage boxes

Queries put labels on the boxes they fill. A mutation shouts "anything labelled Post 7 is out of date", and only those boxes are refilled.

Quick check: What happens when a mutation invalidates a tag a subscribed query provides?

  • Nothing until the page reloads
  • The whole store is reset
  • The mutation is retried
  • That query refetches automatically
Answer

That query refetches automatically — Tags link mutations to the cached queries they affect.