Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-Beautiful-dnd element not draggable after 2,3 tries

Initially the element is draggable from one column to the other, but after 2-3 item drags, items which are on certain index stops draggins, like I'm dragging an item from column-1 index 0 to column-2 index 0, but after 1-2 more tries, index 0 item stops moving, it stops dragging while items at different indexes move. I can't understand the reason behind it, here's the attached code.

    import React, { Component } from "react";
import { Card, Badge } from "react-bootstrap";
import "./projects.scss";
import projectInfo1 from "../../jsonData/projects1";
import { IconContext } from "react-icons";
import { FiPlus } from "react-icons/fi";
import { Droppable, DragDropContext, Draggable } from "react-beautiful-dnd";

class Projects extends Component {
  state = projectInfo1;
  constructor(props) {
    super(props);
    this.onDragEnd = this.onDragEnd.bind(this);
  }
  onDragEnd = (result) => {
    const { destination, source, draggableId } = result;
    if (!destination) {
      return;
    }
    if (
      destination.droppableId === source.droppableId &&
      destination.index === source.index
    ) {
      return;
    }
    const start = this.state.projects[source.droppableId];
    const finish = this.state.projects[destination.droppableId];

    if (start === finish) {
      const newTopicIds = Array.from(start.topicIds);
      newTopicIds.splice(source.index, 1);
      newTopicIds.splice(destination.index, 0, draggableId);

      const newProject = {
        ...start,
        topicIds: newTopicIds,
      };

      const newState = {
        ...this.state,
        projects: {
          ...this.state.projects,
          [newProject.id]: newProject
        }
      }

      this.setState(newState);
      return
    }

    //moving from one list to another 

    const startTopicIds = Array.from(start.topicIds);
    startTopicIds.splice(source.index, 1);
    const newStart = {
      ...start,
      topicIds: startTopicIds,
    };

    const finishTopicIds = Array.from(finish.topicIds);
    finishTopicIds.splice(destination.index, 0, draggableId);
    const newFinish = {
      ...finish,
      topicIds: finishTopicIds,
    };

    const newState = {
      ...this.state,
      projects: {
        ...this.state.projects,
        [newStart.id]: newStart,
        [newFinish.id]: newFinish,
      },
    };
    this.setState(newState);
  };

  render() {
    return (
      <DragDropContext onDragEnd={this.onDragEnd}>
        <div className="projectCards">
          {this.state.projectsOrder.map((projectID) => {
            const project = this.state.projects[projectID];
            return (
              <Card
                className="projectCard"
                bg="light"
                style={{ width: "21rem" }}
                key={project.id}
              >
                <Card.Header color="#366FF0" className="projectcardheader">
                  {project.projectName}
                </Card.Header>
                <Droppable droppableId={project.id}>
                  {(provided) => (
                    <div
                      className="cardcontent"
                      ref={provided.innerRef}
                      {...provided.droppableProps}
                    >
                      {project.topicIds.map((topicid, index) => {
                        const topic = this.state.topics[topicid];
                        return (
                          <Draggable draggableId={topic.id} index={index}>
                            {(provided) => (
                              <Card
                                key={topic.id}
                                className="topicscard"
                                {...provided.draggableProps}
                                {...provided.dragHandleProps}
                                ref={provided.innerRef}
                              >
                                <Card.Title className="topicsheading">
                                  {topic.topicName}
                                </Card.Title>
                                <Card.Text className="topicdescription">
                                  {topic.topicDescription}
                                </Card.Text>
                                <div>
                                  {topic.topicTags ? (
                                    topic.topicTags.map((k) => {
                                      return (
                                        <Badge
                                          variant="primary"
                                          className="tags"
                                        >
                                          {k}
                                        </Badge>
                                      );
                                    })
                                  ) : (
                                    <Badge variant="primary"></Badge>
                                  )}
                                </div>
                              </Card>
                            )}
                          </Draggable>
                        );
                      })}
                      {provided.placeholder}
                    </div>
                  )}
                </Droppable>
                <div className="addnewcard">
                  <IconContext.Provider
                    value={{
                      style: { verticalAlign: "middle" },
                      className: "reacticon",
                    }}
                  >
                    <FiPlus />
                  </IconContext.Provider>{" "}
                  Add another discussion
                </div>
              </Card>
            );
          })}
        </div>
      </DragDropContext>
    );
  }
}
export default Projects;

InitialData:

const projectsInfo1 = {
  topics: {
    "topic-1": {
      id: "topic-1",
      topicName: "Adding a feature: GSoC 1",
      topicDescription:
        "Some quick example text to build on the card title and make up the bulk of the card's content.",
      topicTags: ["ReactJs", "NodeJS"],
    },
    "topic-2": {
      id: "topic-2",
      topicName: "Adding a feature: GSoC 2",
      topicDescription:
        "Some quick example text to build on the card title and make up the bulk of the card's content.",
      topicTags: ["ReactJs", "NodeJS"],
    },
    "topic-3": {
      id: "topic-3",
      topicName: "Adding a feature: GSoC 3",
      topicDescription:
        "Some quick example text to build on the card title and make up the bulk of the card's content.",
      topicTags: ["ReactJs", "NodeJS"],
    },
    "topic-4": {
      id: "topic-4",
      topicName: "Adding a feature: GSoC 4",
      topicDescription:
        "Some quick example text to build on the card title and make up the bulk of the card's content.",
      topicTags: ["ReactJs", "NodeJS"],
    },
    "topic-5": {
      id: "topic-5",
      topicName: "Adding a feature: GSoC 5",
      topicDescription:
        "Some quick example text to build on the card title and make up the bulk of the card's content.",
      topicTags: ["ReactJs", "NodeJS"],
    },
    "topic-6": {
      id: "topic-6",
      topicName: "Adding a feature: GSoC 6",
      topicDescription:
        "Some quick example text to build on the card title and make up the bulk of the card's content.",
      topicTags: ["ReactJs", "NodeJS"],
    },
    "topic-7": {
      id: "topic-7",
      topicName: "Adding a feature: GSoC 7",
      topicDescription:
        "Some quick example text to build on the card title and make up the bulk of the card's content.",
      topicTags: ["ReactJs", "NodeJS"],
    },
    "topic-8": {
      id: "topic-8",
      topicName: "Adding a feature: GSoC 8",
      topicDescription:
        "Some quick example text to build on the card title and make up the bulk of the card's content.",
      topicTags: ["ReactJs", "NodeJS"],
    },
    "topic-9": {
      id: "topic-9",
      topicName: "Adding a feature: GSoC 9",
      topicDescription:
        "Some quick example text to build on the card title and make up the bulk of the card's content.",
      topicTags: ["ReactJs", "NodeJS"],
    },
    "topic-10": {
      id: "topic-10",
      topicName: "Adding a feature: GSoC 10",
      topicDescription:
        "Some quick example text to build on the card title and make up the bulk of the card's content.",
      topicTags: ["ReactJs", "NodeJS"],
    },
  },
  projectsOrder: [
    "Project-2",
    "Project-1",
    "Project-5",
    "Project-4",
    "Project-3",
  ],
  projects: {
    "Project-1": {
      projectName: "Project 1",
      id: "Project-1",
      topicIds: ["topic-1", "topic-2"],
    },
    "Project-2": {
      projectName: "Project 2",
      id: "Project-2",
      topicIds: ["topic-3", "topic-4"],
    },
    "Project-3": {
      projectName: "Project 3",
      id: "Project-3",
      topicIds: ["topic-5", "topic-6"],
    },
    "Project-4": {
      projectName: "Project 4",
      topicIds: ["topic-7", "topic-8"],
      id: "Project-4",
    },
    "Project-5": {
      projectName: "Project   5",
      id: "Project-5",
      topicIds: ["topic-9", "topic-10"],
    },
  },
};

export default projectsInfo1;
like image 817
Devansh_Geek Avatar asked Jun 08 '20 13:06

Devansh_Geek


1 Answers

Don't know if you are still having this problem but I was having the same problem and this fixed it for me.

Your Draggable needs to have a unique key. i.e.

From:

...
return (
   <Draggable draggableId={topic.id} index={index}>
      {(provided) => (
         <Card
...

To:

...
return (
   <Draggable draggableId={topic.id} index={index} key={topic.id}>
      {(provided) => (
         <Card
...

More or less.

like image 88
Jonah Avatar answered Oct 01 '22 23:10

Jonah