katie hudson
katie hudson

Reputation: 2893

React-Query update cache after mutation performed

I have become slightly lost with react-query. Essentially, I have a useQuery to fetch a user from my database. Their details are added to a form and they can update and submit.

The problem I have is that the update is done to a different database. The main database will be batch updated at a later point. As such, instead of refetching the initial data, I need to use setQueryData to update the cache version.

queryClient = useQueryClient()

const { mutate } = useMutation(postUser, {
    onSuccess: async (response) => {
        console.log(response)

        queryClient.cancelQueries('user');
        const previousUser = queryClient.getQueryData('user');
        console.log(previousUser)
        queryClient.setQueryData('user', {
            ...previousUser,
            data: [
              previousUser.data,
              { '@status': 'true' },
            ],
          })
        return () => queryClient.setQueryData('user', previousUser)
    }
})

At the moment I have something like the above. So it calls postUser and gets a response. The response looks something like so

data:
    data:
        user_uid: "12345"
        status: "true"
        message: "User added."
        status: 1
    

I then getQueryData in order to get the cache version of the data, which currently looks like this

data:
    @userUuid: "12345"
    @status: ""
message: "User found."
status: 1

So I need to update the cached version @status to now be true. With what I have above, it seems to add a new line into the cache

data: Array(2)
    0: {@userUuid: "12345", @status: ""}
    1: {@status: "true"}
message: "User found."
status: 1

So how do I overwrite the existing one without adding a new row?

Thanks

Upvotes: 8

Views: 27382

Answers (1)

TkDodo
TkDodo

Reputation: 28793

This is not really react-query specific. In your setQueryData code, you set data to an array with two entries:

data: [
  previousUser.data,
  { '@status': 'true' },
],

first entry = previousUser.data second entry = { '@status': 'true' }

overriding would be something like this:

queryClient.setQueryData('user', {
  ...previousUser,
  data: {
    ...previousUser.data,
    '@status': 'true',
  },
})

On another note, it seems like your mixing optimistic the onMutate callback with the onSuccess callback. If you want to do optimistic updates, you'd implement the onMutate function in a similar way like you've done it above:

  • cancel outgoing queries
  • set data
  • return "rollback" function that can be called onError

This is basically the workflow found here in the docs.

if you implement onSuccess, you're updating the cache after the mutation was successful, which is also a legit, albeit different, use-case. Here, you don't need to return anything, it would be more similar to the updates from mutation responses example.

Upvotes: 7

Related Questions