Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 412
katie hudson Avatar asked Jun 26 '26 21:06

katie hudson


1 Answers

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.

like image 145
TkDodo Avatar answered Jun 28 '26 12:06

TkDodo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!