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

如何在RTK Query中排序缓存数组?拖拽重排货架遇Immer代理问题

问题解决与Immer代理数组交互指南

一、修复乐观更新的排序问题

你的核心问题是直接给draft赋值新数组不会生效——Immer的draft是代理对象,无法通过draft = sortedShelves这种方式替换整个数组,必须通过原地修改draft内容让Immer追踪变化。

方案1:直接操作原draft(推荐)

无需克隆数组,直接在代理数组上更新order并原地排序:

async onQueryStarted(shelvesToReorder, {dispatch, queryFulfilled}) {
  const patchResult = dispatch(
    firestoreApi.util.updateQueryData('getShelves', undefined, draft => {
      // 1. 更新对应货架的order值
      shelvesToReorder.forEach(({id, index}) => {
        const shelf = draft.find(item => item.id === id);
        if (shelf) {
          shelf.order = index;
        }
      });
      // 2. 原地排序(sort是原地修改方法,Immer可追踪)
      draft.sort((a, b) => a.order - b.order);
    })
  );

  try {
    await queryFulfilled;
  } catch {
    patchResult.undo();
  }
}

方案2:用拷贝数组后替换原draft内容

如果坚持使用克隆数组,可通过splice原地替换draft的全部元素:

async onQueryStarted(shelvesToReorder, {dispatch, queryFulfilled}) {
  const patchResult = dispatch(
    firestoreApi.util.updateQueryData('getShelves', undefined, draft => {
      const shelvesCopy = draft.slice();
      shelvesToReorder.forEach(({id, index}) => {
        const shelf = shelvesCopy.find(item => item.id === id);
        if (shelf) {
          shelf.order = index;
        }
      });
      shelvesCopy.sort((a, b) => a.order - b.order);
      // 清空原draft并插入排序后的数组
      draft.splice(0, draft.length, ...shelvesCopy);
    })
  );

  try {
    await queryFulfilled;
  } catch {
    patchResult.undo();
  }
}

二、Immer代理数组交互规则

  • 原地修改方法会被追踪:sort、push、pop、splice、reverse这类直接修改数组本身的方法,Immer代理能捕捉到变化。
  • 返回新数组的方法不自动生效:slice、map、filter这类返回新数组的方法,若不把新数组内容合并回原draft(比如用splice),draft不会发生变化。
  • 禁止直接替换draft引用:draft是Immer创建的代理对象,draft = newArray只是修改了函数内部的变量引用,并未修改代理背后的原始状态,完全无效。

三、调试代理数组状态

直接console.log(draft)会输出Immer的代理对象,看不到真实数据,需使用Immer的current方法:

import { current } from '@reduxjs/toolkit'; // RTK已集成Immer,直接导入即可

// 在updateQueryData回调中使用
console.log(current(draft)); // 输出数组的真实当前状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 14:25:13