3

I've been trying to implement my Reordering list inside my card using react-beautiful-dnd library but I tried everything in a similar way from egghead.io courses but could not get it working. Here's my 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 {
  constructor(props) {
    super(props);
    this.state = {};
    this.onDragEnd = this.onDragEnd.bind(this);
    this.onDragStart = this.onDragStart.bind(this);
  }
  onDragEnd = result => {};
  onDragStart = result => {};

  render() {
    return (
      <div className="projectCards">
        {projectInfo1.projectsOrder.map((projectID) => {
          const project = projectInfo1.projects[projectID];
          return (
            <DragDropContext onDragEnd={this.onDragEnd} onDragStart={this.onDragStart}>
            <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"
                      innerRef={provided.innerRef}
                      {...provided.droppableProps}
                    >
                      {project.topics.map((j, index) => {
                        return (
                          <Draggable draggableId={j.id} index={index}>
                            {(provided) => (
                              <Card
                                key={j.id}
                                className="topicscard"
                                {...provided.draggableProps}
                                {...provided.dragHandleProps}
                                innerRef={provided.innerRef}
                              >
                                <Card.Title className="topicsheading">
                                  {j.topicName}
                                </Card.Title>
                                <Card.Text className="topicdescription">
                                  {j.topicDescription}
                                </Card.Text>
                                <div>
                                  {j.topicTags ? (
                                    j.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>
            </DragDropContext>
          );
        })}
      </div>
    );
  }
}
export default Projects;

Also I'm attaching a photo, its just showing drag cursor on hovering over the card, but nothing happens on drag, any help will save me!

const projectsInfo1 = {

    projectsOrder:['Project-2','Project-1','Project-5','Project-4','Project-3'],
    projects: {
      'Project-1':{
        projectName: "Project 1",
        id:"p1",
        topics:[{
            id:"p1t1",
            topicName: "Adding a feature: GSoC1",
            topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content.",      
            topicTags:['ReactJs','NodeJS']
        },
        {   id:'p1t2',
            topicName: "Adding a feature: GSoC2",
            topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content.",
            topicTags:['ReactJs','NodeJS']     
        },
        {   id:'p1t3',
            topicName: "Adding a feature: GSoC",
            topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content.",
            topicTags:['ReactJs','NodeJS']      
        },
        {   id: 'p1t4',
            topicName: "Adding a feature: GSoC",
            topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content.",
            topicTags:['ReactJs','NodeJS']      
        }],
      },
      'Project-2':{
        projectName: "Project 2",
        id:'p2',
        topics:[{
            id:'p2t1',
            topicName: "Adding a feature: GSoC",
            topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."      
        },
        {   id:'p2t2',
            topicName: "Adding a feature: GSoC",
            topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."      
        },
        {   id:'p2t3',
            topicName: "Adding a feature: GSoC",
            topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."      
        },
        {   id:'p2t4',
            topicName: "Adding a feature: GSoC",
            topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."      
        }],
      },
      'Project-3':{
        projectName: "Project 3",
        id:'p3',
        topics:[{
            id:'p3t1',
            topicName: "Adding a feature: GSoC",
            topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."      
        },
        {   id:'p3t2',
            topicName: "Adding a feature: GSoC",
            topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."      
        },
        {   id:'p3t3',
            topicName: "Adding a feature: GSoC",
            topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."      
        },
        {   id:'p3t4',
            topicName: "Adding a feature: GSoC",
            topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."      
        }],
      },
      'Project-4':{
        projectName: "Project 4",
        id:'p4',
        topics:[{
            id:'p4t1',
            topicName: "Adding a feature: GSoC",
            topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."      
        },
        {   id:'p4t2',
            topicName: "Adding a feature: GSoC",
            topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."      
        },
        {   id:'p4t3',
            topicName: "Adding a feature: GSoC",
            topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."      
        },
        {   id:'p4t4',
            topicName: "Adding a feature: GSoC",
            topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."      
        }],
      },
      'Project-5':{
        projectName: "Project 5",
        id:'p5',
        topics:[{
            id:'p5t1',
            topicName: "Adding a feature: GSoC",
            topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."      
        },
        {   id:'p5t2',
            topicName: "Adding a feature: GSoC",
            topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."      
        },
        {   id:'p5t3',
            topicName: "Adding a feature: GSoC",
            topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."      
        },
        {   id:'p5t4',
            topicName: "Adding a feature: GSoC",
            topicDescription: "Some quick example text to build on the card title and make up the bulk of the card's content."      
        }],
      },
    },
  };

  export default projectsInfo1;
Devansh_Geek
  • 131
  • 2
  • 10

1 Answers1

6

NOTE :

After the conversation in comment , issue was with innerRef

<div innerRef={provided.innerRef} to <div ref={provided.innerRef}

In demo they were using styled component so they are using innerRef, but if you are using simple div then you should use just ref


Issue :

1) it won't work automatically, you need to write code for it on drag end event onDragEnd

2) There is no state management, so even if you make changes on your imported json, it wont be reflected as react have no idea to re-render the dom again.


Solution :

1) Maintain your imported data in state

2) Write some code inside the onDragEnd, check all conditions over there and apply changes on your state accordingly ( Don't mutate the state or it will not reflect the changes )

Note : Below is just code snippet of demo from egghead.io for sorting listing within same droppable area , just give overall idea how it should be

onDragEnd = result => {
  const { destination, source, draggableId } = result

  if (!destination) {
    return
  }

  if (
    destination.droppableId === source.droppableId &&
    destination.index === source.index
  ) {
    return
  }

  const start = this.state.columns[source.droppableId]
  const finish = this.state.columns[destination.droppableId]


  // this is the logic behind sorting state , you have to do it by your self
  if (start === finish) {
    const newTaskIds = Array.from(start.taskIds)
    newTaskIds.splice(source.index, 1)
    newTaskIds.splice(destination.index, 0, draggableId)

    const newColumn = {
      ...start,
      taskIds: newTaskIds
    }

    const newState = {
      ...this.state,
      columns: {
        ...this.state.columns,
        [newColumn.id]: newColumn
      }
    }

    this.setState(newState)
    return
  }
}

WORKING DEMO :

Edit react-beautiful-dnd tutorial

Vivek Doshi
  • 56,649
  • 12
  • 110
  • 122
  • No, Like in this video you can see, https://egghead.io/lessons/react-reorder-a-list-with-react-beautiful-dnd its working for him, even he hasn't written the logic for onDragEnd, same with me, though I wrote it along with imported my data in state, still no change :(/ – Devansh_Geek Jun 08 '20 at 08:32
  • If you see the video, item is just dragable but it's not ordering , as soon as he drops the element it's just reverted to original position – Vivek Doshi Jun 08 '20 at 08:49
  • 1
    Mine is not even lifting from its position. Like its not moving! Its just shows drag cursor icon on hovering – Devansh_Geek Jun 08 '20 at 09:29
  • Is it possible to share code of project? Or link? Git – Vivek Doshi Jun 08 '20 at 09:36
  • What should I send more, should I send my Initial Data too? Its not on github yet as it is not working. I've attached the initial data too. – Devansh_Geek Jun 08 '20 at 09:40
  • 1
    @Devansh_Geek, try to change `
    – Vivek Doshi Jun 08 '20 at 09:48
  • Oh, now its working! Thanks a lot dude, you made my day! I was just about to start looking into tutorials for react-dnd and implementing that. Thanks again – Devansh_Geek Jun 08 '20 at 10:17
  • 4
    Yes, even with styled components, it appears that you have to use ref={provided.innerRef}. I wasted a ton of time on this one. I sure wish the tutorial would be updated on egghead.io – Marc Aug 09 '20 at 20:45