Back to Dnd Kit

Migration guide

apps/docs/react/guides/migration.mdx

latest7.1 KB
Original Source
<Steps> <Step title="Update dependencies"> Update your `package.json` and install the new packages:
```diff
  "dependencies": {
-   "@dnd-kit/core": "^x.x.x"
-   "@dnd-kit/sortable": "^x.x.x"
-   "@dnd-kit/utilities": "^x.x.x"
+   "@dnd-kit/react": "^x.x.x"
+   "@dnd-kit/helpers": "^x.x.x"
  }
```

After updating your package.json, install the new dependencies with your package manager of choice.
</Step> <Step title="Migrate context provider"> Update your context provider. The new [DragDropProvider](/react/components/drag-drop-provider) replaces the legacy `DndContext`:
<CodeGroup>
```tsx Before
import {DndContext} from '@dnd-kit/core';

function App() {
  return (
    <DndContext
      onDragStart={({active}) => {
        console.log(`Started dragging ${active.id}`);
      }}
      onDragEnd={({active, over}) => {
        if (over) {
          console.log(`Dropped ${active.id} over ${over.id}`);
        }
      }}
      onDragCancel={({active}) => {
        console.log(`Cancelled dragging ${active.id}`);
      }}
    >
      <YourComponents />
    </DndContext>
  );
}
```

```tsx After {1,6-8,10-24}
import {DragDropProvider} from '@dnd-kit/react';

function App() {
  return (
    <DragDropProvider
      onDragStart={(event, manager) => {
        const {operation} = event;
        console.log(`Started dragging ${operation.source.id}`);
      }}
      onDragEnd={(event, manager) => {
        const {operation, canceled} = event;
        const {source, target} = operation;

        if (canceled) {
          // Replaces onDragCancel
          console.log(`Cancelled dragging ${source.id}`);
          return;
        }

        if (target) {
          console.log(`Dropped ${source.id} over ${target.id}`);
          // Access rich data
          console.log('Source data:', source.data);
          console.log('Drop position:', operation.position.current);
        }
      }}
    >
      <YourComponents />
    </DragDropProvider>
  );
}
```
</CodeGroup>

<Info>
  The new provider gives you access to the `manager` instance in event handlers, enabling more advanced control over the drag and drop system.
</Info>
</Step> <Step title="Update draggable components"> Update your [draggable](/concepts/draggable) components using the new [useDraggable](/react/hooks/use-draggable) hook:
<CodeGroup>
```tsx Before
function DraggableItem({id}) {
  const {
    attributes,
    listeners,
    setNodeRef,
    transform
  } = useDraggable({
    id
  });

  return (
    <div
      ref={setNodeRef}
      {...listeners}
      {...attributes}
      style={{
        transform: CSS.Transform.toString(transform)
      }}
    >
      Item {id}
    </div>
  );
}
```

```tsx After {2-4,7-8}
function DraggableItem({id}) {
  const draggable = useDraggable({
    id,
  });

  return (
    <div
      ref={draggable.ref}
      className={isDragging ? 'dragging' : ''}
    >
      Item {id}
    </div>
  );
}
```
</CodeGroup>
</Step> <Step title="Update droppable components"> Update your [droppable](/concepts/droppable) components using the new [useDroppable](/react/hooks/use-droppable) hook:
<CodeGroup>
```tsx Before
function Dropzone() {
  const {setNodeRef, isOver} = useDroppable({
    id: 'drop-zone'
  });

  return (
    <div
      ref={setNodeRef}
      style={{
        background: isOver ? 'lightblue' : 'white'
      }}
    >
      Drop here
    </div>
  );
}
```

```tsx After {2,8,10}
function Dropzone() {
  const droppable = useDroppable({
    id: 'drop-zone'
  });

  return (
    <div
      ref={droppable.ref}
      style={{
        background: droppable.isDropTarget ? 'green' : 'white'
      }}
    >
      Drop here
    </div>
  );
}
```
</CodeGroup>
</Step> <Step title="Update drag overlay"> The [DragOverlay](/react/components/drag-overlay) component has been simplified:
<CodeGroup>
```tsx Before
function App() {
  const [activeId, setActiveId] = useState(null);

  return (
    <DndContext
      onDragStart={() => setActiveId('item')}
      onDragEnd={() => setActiveId(null)}
    >
      <Draggable id="item" />
      <DragOverlay>
        {activeId ? <Item id={activeId} /> : null}
      </DragOverlay>
    </DndContext>
  );
}
```

```tsx After {2,5,7-9}
function App() {
  return (
    <DragDropProvider>
      <Draggable id="item" />
      <DragOverlay>
        {source => (
          <Item id={source.id} />
        )}
      </DragOverlay>
    </DragDropProvider>
  );
}
```
</CodeGroup>

<Warning>
  Only render the `DragOverlay` component once per `DragDropProvider`. The hooks have no effect when used within the overlay.
</Warning>
</Step> <Step title="Migrate sortable components"> Update your sortable components using the new [useSortable](/react/hooks/use-sortable) hook:
<CodeGroup>
```tsx Before
import {useSortable} from '@dnd-kit/sortable';

function SortableItem({id, index}) {
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition
  } = useSortable({
    id,
    index
  });

  return (
    <div
      ref={setNodeRef}
      {...attributes}
      {...listeners}
      style={{
        transform: CSS.Transform.toString(transform),
        transition
      }}
    >
      Item {id}
    </div>
  );
}
```

```tsx After {1,4-7,10-11}
import {useSortable} from '@dnd-kit/react/sortable';

function SortableItem({id, index}) {
  const sortable = useSortable({
    id,
    index
  });

  return (
    <div
      ref={sortable.ref}
      className={sortable.isDragging ? 'dragging' : undefined}
    >
      Item {id}
    </div>
  );
}
```
</CodeGroup>

Use the array manipulation helpers from `@dnd-kit/helpers` to handle reordering.
</Step> </Steps>

Next steps

<CardGroup cols={2}> <Card title="Quickstart guide" icon="rocket" href="/react/quickstart" > Build beautiful drag and drop interfaces in minutes with the new dnd kit </Card> <Card title="Draggable elements" icon="bullseye-pointer" href="/concepts/draggable" > Learn how to make elements draggable with the new API </Card> <Card title="Droppable targets" icon="expand" href="/concepts/droppable" > Create drop zones and handle collision detection </Card> <Card title="Sortable lists" icon="layer-group" href="/concepts/sortable" > Build sortable interfaces with array manipulation helpers </Card> </CardGroup>