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

拖拽调整对象priority时函数异常:目标项优先级未正确更新

问题:拖拽调整数组对象priority值时异常(低优先级项拖至高位置失效)

我编写了updatePriorities函数用于拖拽调整数组中对象的priority值,但发现当低优先级项拖到高优先级位置时,目标项的priority无法正确更新;反之高优先级项拖到低位置时运行正常。

原函数代码

export const updatePriorities = (data, draggedItem, targetItem) => {
  const draggedItemPriority = draggedItem?.priority;
  const targetItemPriority = targetItem?.priority;

  if (draggedItemPriority === undefined || targetItemPriority === undefined || draggedItemPriority === null || targetItemPriority === null) {
    return data;
  }

  const minPriority = Math.min(draggedItemPriority, targetItemPriority);
  const maxPriority = Math.max(draggedItemPriority, targetItemPriority);

  const newData = map(data, (item) => {
    if (item.priority === draggedItemPriority) {
      return { ...item, priority: targetItemPriority };
    } else if (item.priority >= minPriority && item.priority < maxPriority) {
      const priorityOffset = targetItemPriority < draggedItemPriority ? 1 : -1;
      return { ...item, priority: item.priority + priorityOffset };
    } else if (item.priority === targetItemPriority) {
      return { ...item, priority: draggedItemPriority };
    }
    return item;
  });

  return orderBy(newData, 'priority');
};

测试数据

const mockedData = [
  { name: 'Item 0', priority: 0 },
  { name: 'Item 1', priority: 1 },
  { name: 'Item 2', priority: 2 },
  { name: 'Item 3', priority: 3 },
  { name: 'Item 4', priority: 4 },
  { name: 'Item 5', priority: 5 }
];

const mockedDraggedItem1 = mockedData[1]; // priority=1
const mockedTargetItem1 = mockedData[3]; // priority=3

错误结果与预期结果

调用updatePriorities(mockedData, mockedDraggedItem1, mockedTargetItem1)后得到错误结果:

[
    {name: "Item 0", priority: 0},
    {name: "Item 2", priority: 1},
    {name: "Item 3", priority: 1}, // 此处错误,应为2
    {name: "Item 1", priority: 3},
    {name: "Item 4", priority: 4},
    {name: "Item 5", priority: 5}
]

预期结果:

[
    {name: "Item 0", priority: 0},
    {name: "Item 2", priority: 1},
    {name: "Item 3", priority: 2},
    {name: "Item 1", priority: 3},
    {name: "Item 4", priority: 4},
    {name: "Item 5", priority: 5}
]

问题原因与修复方案

问题根源

原逻辑的核心问题是遍历过程中修改的值干扰了后续判断:
当拖拽低优先级项(priority=1)到高位置(priority=3)时:

  1. 先处理原拖拽项(priority=1),将其改为3;
  2. 处理到priority=2的项时,因为min=1,max=3,满足>=min && <max,所以减1变成1;
  3. 最后处理原目标项(priority=3)时,此时拖拽项的priority已经被改成3,导致item.priority === draggedItemPriority条件先触发,跳过了item.priority === targetItemPriority的分支,目标项的priority未被正确修改。

修复后的代码

export const updatePriorities = (data, draggedItem, targetItem) => {
  const draggedItemPriority = draggedItem?.priority;
  const targetItemPriority = targetItem?.priority;

  if (draggedItemPriority === undefined || targetItemPriority === undefined || draggedItemPriority === null || targetItemPriority === null) {
    return data;
  }

  // 提前判断拖拽方向:低优先级拖到高位置为true
  const isDraggingUp = targetItemPriority > draggedItemPriority;

  const newData = data.map(item => {
    const currentPriority = item.priority;
    
    // 先处理拖拽项与目标项的交换,基于原始优先级判断
    if (currentPriority === draggedItemPriority) {
      return { ...item, priority: targetItemPriority };
    }
    if (currentPriority === targetItemPriority) {
      return { ...item, priority: draggedItemPriority };
    }

    // 根据拖拽方向处理中间项
    if (isDraggingUp) {
      // 低优先级拖到高位置:中间项(原拖拽项+1 到 目标项-1)减1
      if (currentPriority > draggedItemPriority && currentPriority < targetItemPriority) {
        return { ...item, priority: currentPriority - 1 };
      }
    } else {
      // 高优先级拖到低位置:中间项(原目标项+1 到 拖拽项-1)加1
      if (currentPriority > targetItemPriority && currentPriority < draggedItemPriority) {
        return { ...item, priority: currentPriority + 1 };
      }
    }

    return item;
  });

  return orderBy(newData, 'priority');
};

修复关键点

  1. 基于原始优先级判断:全程使用未修改的draggedItemPriority和targetItemPriority做条件判断,避免遍历中修改的值干扰逻辑;
  2. 拆分拖拽方向:明确区分向上(低→高)和向下(高→低)拖拽的场景,分别处理中间项的范围,避免用min/max导致的逻辑模糊;
  3. 调整判断顺序:先处理拖拽项与目标项的交换,再处理中间项,避免条件冲突。

验证结果

调用修复后的函数,会得到预期的正确结果,目标项的priority被正确更新为2,中间项的优先级也符合拖拽排序逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 15:27:07