R

React dnd Kit Tutorial

Drag and Drop en React

Volver al contenido

Copiar enlace

En este tutorial vamos a crear una aplicacion de React que nos permita reordenar elementos de una lista usando un modulo llamado React dnd Kit.

Creacion del Proyecto

Primero crearemos un proyecto usando Vitejs, a traves del siguiente comando:

npm create vite

Con las siguientes configuraciones:

√ Project name: ... react-dnd-kit-tutorial
√ Select a framework: » React
√ Select a variant: » JavaScript

Ahora ejecutemos el proyecto, usando los comandos:

cd react-dnd-kit-tutorial
npm install
npm run dev

Limpiemos el proyecto

Antes de empezar a escribir codigo, primero limpiemos el proyecto de codigo y archivos innecesarios, primero vamos a ir en App.jsx, dejandolo asi:

function App() {
  return (
    <div>App</div>
  )
}

export default App

Luego elimina el archivo App.css

Y en index.css quita todo el contenido dejando vacio el archivo.

Instalacion de TailwindCSS

Ahora vamos a instalar TailwindCSS, para eso puedes seguir esta guia de la documentación: https://tailwindcss.com/docs/guides/vite

Instalacion de React Dnd Kit

npm i @dnd-kit/core @dnd-kit/utilities @dnd-kit/sortable

en App.jsx, creemos un contexto para los elementos que vamos a arrastrar:

import { DndContext, closestCenter } from "@dnd-kit/core";
import { useState } from "react";

function App() {
  const [people, setPeople] = useState([
    { id: 1, name: "John" },
    { id: 2, name: "Sarah" },
    { id: 3, name: "Paul" },
  ]);

  const handleDragEnd = (event) => {
    console.log("drag end");
  };

  return (
    <DndContext collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
      <h1 className="text-2xl font-bold">Users List</h1>
    </DndContext>
  );
}

export default App;

SortableContext

Ahora crearemos un componente que sera el contenedor de cada uno de los elementos que queremos arrastrar verticalmente en pantalla, este componente es el SortableContext

import { SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";

...

  return (
    <DndContext collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
      <h1 className="text-2xl font-bold">Users List</h1>
      <SortableContext
        items={people}
        strategy={verticalListSortingStrategy}
      >
        {/* components */}
      </SortableContext>
    </DndContext>
  );

Luego crearemos un componente llamado UserItem.jsx, que sera un solo elemento que muestre un usuario:

import { useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";

function User({ user }) {
  const { attributes, listeners, setNodeRef, transform, transition } =
    useSortable({ id: user.id });

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
  };

  return (
    <div
      style={style}
      ref={setNodeRef}
      {...attributes}
      {...listeners}
      className="bg-white p-4 rounded-md shadow-md"
    >
      <h1>{user.name}</h1>
    </div>
  );
}

export default User;

En este componente usamos el hook de dnd-kit llamado useSortable que nos da unas propiedades que simplemente tenemos que pasar al contenedor del componente para que este pueda ser arrastrado.

Luego crearemos una lista de estos usuarios en el contendor en App.jsx

<DndContext
  collisionDetection={closestCenter}
  onDragEnd={handleDragEnd}
>
  <h1 className="text-2xl font-bold">Users List</h1>
  <SortableContext
    items={people}
    strategy={verticalListSortingStrategy}
  >
    {people.map((user) => (
      <User key={user.id} user={user} />
    ))}
  </SortableContext>
</DndContext>

tambien añadiremos unos estilos para que apareza centrado la lista:

  return (
    <div className="flex justify-center items-center">
      <div className="w-4/6">
        <DndContext
          collisionDetection={closestCenter}
          onDragEnd={handleDragEnd}
        >
          <h1 className="text-2xl font-bold">Users List</h1>
          <SortableContext
            items={people}
            strategy={verticalListSortingStrategy}
          >
            {people.map((user) => (
              <User key={user.id} user={user} />
            ))}
          </SortableContext>
        </DndContext>
      </div>
    </div>
  );

Ahora ya puedes arrastrar los elementos pero estos aun no se mantienen en la posicion en que lo estas colocando. Esto es porque el estado noe esta cambiando, asi que en cada arrastrada de elemento, cuando acabe el estado debe actualizarse, esto lo puedes hacer en la funcion handleDragEnd:

import {
    ...
  arrayMove,
} from "@dnd-kit/sortable";

  const handleDragEnd = (event) => {
    const { active, over } = event;
    console.log("active", active.id);
    console.log("over", over.id);

    if (!active.id !== over.id) {
      setPeople((people) => {
        const oldIndex = people.findIndex((person) => person.id === active.id);
        const newIndex = people.findIndex((person) => person.id === over.id);

        console.log(arrayMove(people, oldIndex, newIndex));
        return arrayMove(people, oldIndex, newIndex);
      });
    }

    console.log("drag end");
  };

Listo cone esto ya tienes ordenado el arreglo y ahora solo tienes que guardar ese arreglo quizas enviandolo a una API o en el localstorageo o donde lo necesites.

Más Recursos

Otras Bibliotecas Similares

Esta biblioteca tambien puedes usarla en reemplazo de bibliotecas como React Beautiful Dnd que ya no le estan dando mantenimiento:

Actualizado por ultima vez el

Aprende a crear una aplicacion que te permite hacer drag and drop usando la biblioteca de React dnd Kit

¿Quieres Compatir mi Contenido?

Publicado:hace 3 años

Actualizado:hace un año

;