You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Query执行mutation后如何用setQueryData正确更新缓存不新增条目

React Query 缓存字段覆盖修改方案

问题根源

你当前的写法误将原本为对象类型的data字段修改为了数组结构:你把原用户数据对象和新的@status对象共同放到了数组中,才会出现缓存中data变成数组、新增额外条目的问题。

修改后的代码

方案1:提交成功后再更新缓存(适配你当前的逻辑调整)

const queryClient = useQueryClient()

const { mutate } = useMutation(postUser, {
    onSuccess: async (response) => {
        console.log(response)
        // 取消正在进行的user查询,避免自动同步覆盖手动更新
        await queryClient.cancelQueries('user');
        const previousUser = queryClient.getQueryData('user');
        console.log(previousUser)
        queryClient.setQueryData('user', {
            ...previousUser,
            // 对原有data对象做扩展,直接覆盖@status字段,保持对象类型不变
            data: {
              ...previousUser.data,
              // 可以直接硬写值,也可以从接口响应中取:response.data.data.status
              '@status': 'true'
            },
          })
    },
    // 可选:更新失败时回滚到旧数据
    onError: () => {
        queryClient.invalidateQueries('user')
    }
})

方案2:乐观更新(提交前就更新缓存,失败自动回滚)

如果你想要提交操作更快的响应体验,可以用乐观更新写法,把缓存更新逻辑放到onMutate回调中:

const queryClient = useQueryClient()

const { mutate } = useMutation(postUser, {
    // 提交请求前先更新缓存
    onMutate: async () => {
        await queryClient.cancelQueries('user');
        const previousUser = queryClient.getQueryData('user');
        queryClient.setQueryData('user', {
            ...previousUser,
            data: {
              ...previousUser.data,
              '@status': 'true'
            },
        })
        // 返回回滚函数,后续出错时调用
        return () => queryClient.setQueryData('user', previousUser)
    },
    // 请求出错时回滚缓存
    onError: (err, variables, rollback) => {
        rollback?.()
    }
})

核心修改点

  • 不再将data字段赋值为数组,改为对原有previousUser.data对象做展开扩展
  • 直接覆盖需要修改的@status字段,保留原有data对象的其他所有字段,不会新增额外条目

内容的提问来源于stack exchange,提问作者katie hudson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 23:24:01