使用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
相关产品推荐
相关产品推荐

