# Caching, Tags and Invalidation — Redux Toolkit / Zustand

Source: https://www.skillbyai.com/en/redux-zustand/q-tags

> 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.

```typescript
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.

**Quiz:** 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
- [x] That query refetches automatically

*Answer:* That query refetches automatically. Tags link mutations to the cached queries they affect.
