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

使用DND-Kit时Transform和Translate数据为null/undefined的问题

问题原因及解决方案

问题1:SortableItem未导入核心Hook

你的SortableItem组件使用了useSortable但未导入,导致无法获取拖拽状态相关的transform、transition等数据,直接造成样式失效。

修正后的SortableItem代码:

import { useSortable } from '@dnd-kit/sortable'; // 补充缺失的导入
import { CSS } from "@dnd-kit/utilities";

export function SortableItem(props) {
  const { attributes, listeners, setNodeRef, transform, transition } =
    useSortable({ id: props.id });

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
    cursor: "grabbing",
    backgroundColor: "white",
    border: "1px solid black",
    boxShadow: "1px 1px 2px grey",
    marginBottom: '10px', // 可选:增加间距提升拖拽体验
  };

  return (
    <div ref={setNodeRef} style={style} {...attributes} {...listeners}>
      {props.children}
    </div>
  );
}

问题2:SortableContext的items参数错误

SortableContext要求items传入元素ID数组,而非完整的对象数组,否则dnd-kit无法正确识别可排序项的标识。

问题3:拖拽结束时索引获取逻辑错误

elements是对象数组,直接用items.indexOf(active.id)无法匹配到对应元素,需要通过ID遍历查找索引。

修正后的App.js代码:

import 'bootstrap/dist/css/bootstrap.min.css';
import Container from 'react-bootstrap/Container';
import {
  DndContext,
  closestCenter
} from "@dnd-kit/core";
import {
  SortableContext,
  arrayMove,
  verticalListSortingStrategy
} from '@dnd-kit/sortable';
import { SortableItem } from './sortableItem';
import {useState} from 'react';
import NewTextBlock from './NewTextBlock';
import TextBlock from './TextBlock';
import NewBlock from './NewBlock';

function App() {
  const [elements, setElements] = useState([
  {
    name : "Block1",
    element : <NewTextBlock />
  }, 
  {
    name : "Block2",
    element : <TextBlock />
  },
  {
    name : "Block3",
    element : <NewBlock />
  }]);

  function handleDragEnd(e){
    const {active, over} = e;
    console.log("active : " + active.id);
    console.log("over : " + over.id);
    if(active.id !== over.id){
      setElements((items) => {
        // 修正索引查找逻辑:根据ID匹配对象
        const activeIndex = items.findIndex(item => item.name === active.id);
        const overIndex = items.findIndex(item => item.name === over.id);

        return arrayMove(items, activeIndex, overIndex);
      })
    }
  }

  return (
    <DndContext
      collisionDetection={closestCenter}
      onDragEnd={handleDragEnd}
    >
      
      <Container className='p-3' style={{width : "50%"}} align="center"> 
        <h3>Lol what</h3>
        <SortableContext
          items={elements.map(item => item.name)} // 改为传入ID数组
          strategy={verticalListSortingStrategy}
        >
          {elements.map((block) => {
            return(
              <SortableItem key={block.name} id={block.name}>
                {block.element}
              </SortableItem>
            )
          })}
        </SortableContext>
      </Container>
    </DndContext>
  );
}

export default App;

验证效果

修改后,拖拽时transform和transition会正确获取到位移数据,元素拖拽的视觉反馈会正常生效,同时拖拽结束后的数组排序逻辑也能正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 13:32:42