1

Currently getting my head into React and DND for the first time. I have created a small example application where I try to implement a basic functionality of DND.

I´m running into two issues:

  1. After I drop an item and reorder the state object (and set the state) the items get reseted to the inital state.

  2. After the first drop I cannot drag all items further as they seem to not be associated with the draggable id anymore.

This screenshot shows that the source and destination id is different and also that the object order of the state has changed (onDragEnd function). Also the second issue described is shown, that the draggable id is not available anymore.

Issues

Here is my code

import { PlusCircleOutlined } from "@ant-design/icons/lib/icons";
import { Row, Col, Button, Divider } from "antd";
import { useState } from "react";

import {
  DragDropContext,
  Draggable,
  Droppable,
  DroppableProvided,
  DraggableLocation,
  DropResult,
  DroppableStateSnapshot,
  DraggableProvided,
  DraggableStateSnapshot,
} from "react-beautiful-dnd";

import Note from "../note/Note";

function Home() {
  const [notes, setNotes] = useState([
    { title: "Hallo", text: "BlaBla" },
    { title: "Hallo1", text: "BlaBla1" },
    { title: "Hallo2", text: "BlaBla1" },
  ]);
  function onDelete(index: number) {
    const newNotes = [...notes];
    newNotes.splice(index, 1);
    setNotes(newNotes);
  }

  function onEdit(index: number, title: string, text: string) {
    const newNotes = [...notes];
    newNotes[index].title = title;
    newNotes[index].text = text;
    setNotes(newNotes);
  }

  function onCreateNote() {
    let notesCount = notes.length;
    setNotes((notes) => [
      ...notes,
      { title: "New" + notesCount, text: "New text" },
    ]);
  }

  function onDragEnd(result: DropResult): void {
    console.log("DRAG END");
    console.log(result);

    const { source, destination } = result;

    if (!destination) {
      return;
    }

    console.log(notes);
    const newNotes = [...notes];
    const [removed] = newNotes.splice(source.index, 1);
    newNotes.splice(destination.index, 0, removed);
    console.log(newNotes);
    setNotes(newNotes);

    //Wenn mehr als eine liste
    /* if (source.droppableId === destination.droppableId) {
      return;
    } */
  }

  return (
    <div>
      <Row>
        <Col xs={2} sm={4} md={6} lg={6} xl={6}>
          <Button
            type="primary"
            shape="round"
            size="large"
            icon={<PlusCircleOutlined />}
            onClick={() => onCreateNote()}
          >
            Create new note
          </Button>
        </Col>
      </Row>
      <Divider></Divider>

      <DragDropContext onDragEnd={onDragEnd}>
        <Droppable droppableId="droppable">
          {(provided: DroppableProvided, snapshot: DroppableStateSnapshot) => (
            <div
              ref={provided.innerRef}
              {...provided.droppableProps}
              /*  style={getListStyle(snapshot.isDraggingOver)} */
            >
              <Row gutter={[16, { xs: 8, sm: 16, md: 24, lg: 32 }]}>
                {notes.map((value, index) => (
                  <Col
                    className="gutter-row"
                    xs={2}
                    sm={4}
                    md={6}
                    lg={6}
                    xl={6}
                    key={index}
                  >
                    <Draggable
                      key={index}
                      draggableId={value.title}
                      index={index}
                    >
                      {(providedDraggable: DraggableProvided) => (
                        <div
                          ref={providedDraggable.innerRef}
                          {...providedDraggable.draggableProps}
                          {...providedDraggable.dragHandleProps}
                        >
                          <Note
                            onDelete={() => onDelete(index)}
                            onEdit={(title: string, text: string) =>
                              onEdit(index, title, text)
                            }
                            noteTitle={value.title}
                            noteText={value.text}
                          />
                        </div>
                      )}
                    </Draggable>
                  </Col>
                ))}
              </Row>
              {provided.placeholder}
            </div>
          )}
        </Droppable>
      </DragDropContext>
    </div>
  );
}

export default Home;

Any idea what I´m missing here?

el solo lobo
  • 973
  • 11
  • 23
  • 1
    This is a duplicate of this question: https://stackoverflow.com/questions/60029734/react-beautiful-dnd-i-get-unable-to-find-draggable-with-id-1 Keeping indexes as keys is always risky whilst using React and that too whilst reording the UI that is made via loop. Here is a working draft of your own example: https://codesandbox.io/s/react-typescript-forked-uqumom?file=/src/App.tsx Try and find a unique value within your data that can be kept as an ID for both the Draggable and Col component! – Mujeeb Qureshi Mar 23 '22 at 21:40

0 Answers0