Mutations
Unlike useQuery
, useMutation
returns a tuple. The first item in the tuple is the trigger
function and the second element contains an object with status
, error
, and data
. Additionally, useMutation
also makes internalQueryArgs
, originalArgs
,
and endpoint
available for inspection.
Also unlike the useQuery
hook, the useMutation
hook doesn't execute automatically. To run a mutation you have to call the trigger
function.
Basic mutation
This is a modified version of the complete example you can see at the bottom of the page to highlight the updatePost
mutation. In this scenario, a post is fetched with useQuery
, and then a EditablePostName
component is rendered that allows us to edit the name of the post.
Advanced mutations with revalidation
In the real world, it's very common that a developer would want to resync their local data cache with the server after performing a mutation (aka revalidation
). RTK Query takes a more centralized approach to this and requires you to configure the invalidation behavior in your API service definition. Before getting started, let's cover some new terms:
- Entities
- In short, entities are just a name that you can give to a specific collection of data to control caching and invalidation behavior. For example, in an application that has both
Posts
andUsers
, you would defineentityTypes: ['Posts', 'Users']
when callingcreateApi
.
- Provides
- A
query
can provide entities to the cache.- Accepts either an array of
{type: string, id?: string|number}
or a callback that returns such an array. That function will be passed the result as the first argument and the argument originally passed into thequery
method as the second argument.
- Accepts either an array of
- Invalidates
- A
mutation
can invalidate specific entities in the cache.- Can both be an array of
{type: string, id?: string|number}
or a callback that returns such an array. That function will be passed the result as the first argument and the argument originally passed into thequery
method as the second argument.
- Can both be an array of
Scenarios and Behaviors
RTK Query provides a lot of flexibility for how you can manage the invalidation behavior of your service. Let's look at a few different scenarios:
Invalidating everything
What to expect
When addPost
is triggered, it would cause each PostDetail
component to go back into a isFetching
state because addPost
invalidates the root entity, which causes every query that provides 'Posts' to be re-run. In most cases, this may not be what you want to do. Imagine if you had 100 posts on the screen that all subscribed to a getPost
query โ in this case, you'd create 100 requests and send a ton of unnecessary traffic to your server, which we're trying to avoid in the first place! Even though the user would still see the last good cached result and potentially not notice anything other than their browser hiccuping, you still want to avoid this.
Selectively invalidating lists
Keep an eye on the provides
property of getPosts
- we'll explain why after.
Note about 'LIST' and
id
s
LIST
is an arbitrary string - technically speaking, you could use anything you want here, such asALL
or*
. The important thing when choosing a custom id is to make sure there is no possibility of it colliding with an id that is returned by a query result. If you have unknown ids in your query results and don't want to risk it, you can go with point 3 below.- You can add many entity types for even more control
[{ type: 'Posts', id: 'LIST' }, { type: 'Posts', id: 'SVELTE_POSTS' }, { type: 'Posts', id: 'REACT_POSTS' }]
- If the concept of using an
id
like 'LIST' seems strange to you, you can always add anotherentityType
and invalidate it's root, but we recommend using theid
approach as shown.
What to expect
When addPost
is fired, it will only cause the PostsList
to go into an isFetching
state because addPost
only invalidates the 'LIST' id, which causes getPosts
to rerun (because it provides that specific id). So in your network tab, you would only see 1 new request fire for GET /posts
. Once that resolves and assuming it returned updated data for ids 1, 2, and 3, the PostDetail
components would then rerender with the latest data.
Commented Posts Service
This is an example of a CRUD service for Posts. This implements the Selectively invalidating lists strategy and will most likely serve as a good foundation for real applications.