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

react-beautiful-dnd拖拽后,如何将对象数组position设为数组索引?

解决react-beautiful-dnd拖拽后更新元素position属性的问题

核心要注意保持数组的不可变性,同时在重排后遍历新数组,给每个元素的position赋值当前索引。以下是完整实现步骤和代码示例:

1. 拖拽逻辑与position更新结合

假设你的characters是用useState管理的状态:

import { useState } from 'react';
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';

function DragList() {
  const [characters, setCharacters] = useState([
    { id: '1', name: 'A', position: 0 },
    { id: '2', name: 'B', position: 1 },
    { id: '3', name: 'C', position: 2 },
  ]);

  const handleOnDragEnd = (result) => {
    // 无有效拖拽目标或位置未变化时直接返回
    if (!result.destination || result.source.index === result.destination.index) return;

    // 1. 复制原数组,避免直接修改原状态
    const newCharacters = Array.from(characters);
    // 2. 执行拖拽重排逻辑
    const [draggedItem] = newCharacters.splice(result.source.index, 1);
    newCharacters.splice(result.destination.index, 0, draggedItem);

    // 3. 遍历新数组,更新每个元素的position为当前索引
    const updatedCharacters = newCharacters.map((item, index) => ({
      ...item,
      position: index,
    }));

    // 4. 更新状态
    setCharacters(updatedCharacters);
  };

  return (
    <DragDropContext onDragEnd={handleOnDragEnd}>
      <Droppable droppableId="characters">
        {(provided) => (
          <div {...provided.droppableProps} ref={provided.innerRef}>
            {characters.map((item, index) => (
              <Draggable key={item.id} draggableId={item.id} index={index}>
                {(provided) => (
                  <div
                    ref={provided.innerRef}
                    {...provided.draggableProps}
                    {...provided.dragHandleProps}
                  >
                    {item.name} - position: {item.position}
                  </div>
                )}
              </Draggable>
            ))}
            {provided.placeholder}
          </div>
        )}
      </Droppable>
    </DragDropContext>
  );
}

export default DragList;

2. 原for循环失效的常见原因

大概率是以下两种情况:

  • 直接修改原数组(比如characters[i].position = i),React无法检测到状态变化,因为数组引用未改变;
  • 循环后未重新设置状态,或设置的仍是原数组的引用。

用Array.from复制数组,再通过map生成新的元素对象(保持不可变性),最后更新状态,既能让React感知到变化,也能确保每个元素的position正确对应数组索引。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 04:55:45