Redux Toolkit中过滤对象数组缓存无效果问题求助
解决Redux Toolkit updateQueryData中数组过滤无效果的问题
你的过滤操作失效的核心原因是Immer的使用方式错误:在updateQueryData的draft回调里,你直接给draft重新赋值了(draft = draft.filter(...)),但Immer要求必须修改原draft数组本身,而不是替换整个变量引用——因为Immer是通过代理原数组来追踪变更的,重新赋值会让Immer丢失对原数组的追踪,导致你的修改不会同步到缓存中。
修复步骤
- 替换数组修改方式:不要直接赋值
draft,而是用数组的splice方法清空原数组,再把过滤后的元素添加进去;或者直接修改原数组的内容。 - 修复reduce的初始值:你的
reduce没有传入初始值,当reminders数组为空时会报错,需要补充符合Partial<Reminder>结构的初始值。
修改后的代码示例
combineReminders: builder.mutation<Reminder, Partial<Reminder>[]>({ query: ([...reminders]) => ({ url: "/", method: "PUT", body: reminders, }), async onQueryStarted([...reminders], { dispatch, queryFulfilled }) { const combineResult = dispatch( reminderApi.util.updateQueryData( "getReminders", undefined, (draft: Partial<Reminder>[]) => { const ids = reminders.map((item) => item.id); console.log("ids:", ids); // 给reduce添加初始值,避免空数组报错 const result = reminders.reduce((acc, reminder) => { const { priority, date, time } = reminder; const compareDates = ( date1: Date | undefined, date2: Date | undefined ) => { if (!date1) return date2; if (!date2) return date1; return date1 < date2 ? date2 : date1; }; const compareTimes = ( time1: string | undefined, time2: string | undefined ) => { if (!time1) return time2; if (!time2) return time1; return new Date(time1) < new Date(time2) ? time2 : time1; }; return { ...acc, date: compareDates(date, acc.date) || date, time: compareTimes(time, acc.time) || time, priority: priority, }; }, {} as Partial<Reminder>); // 补充初始值 // 正确修改draft数组的方式:先清空原数组,再添加过滤后的元素 const filtered = draft.filter(item => ids.includes(item.id)); draft.splice(0, draft.length, ...filtered); // 如果需要添加合并后的result,取消下面的注释 // draft.push(result); console.log(draft); } ) ); try { await queryFulfilled; } catch (error) { combineResult.undo(); } }, }),
关键说明
- Immer的draft是一个代理对象,所有修改必须直接作用于这个代理对象本身,比如用
splice、push、pop等数组方法,或者修改对象的属性;不能通过重新赋值变量的方式来替换整个对象/数组。 - 你的PUT方法和过滤逻辑无关,问题完全出在Immer的使用规范上,和HTTP方法没有关系。
内容的提问来源于stack exchange,提问作者Mathew
相关产品推荐
相关产品推荐

