Drag drop in React.js

Viewed 379

I'm trying to make a drag-drop functionality on a webpage but unsuccessful so far. I want to make the A, B, C cards in the pink box stay where they are after we drag a copy of them to the black box (like a menu box, link for a demo of this behavior). I don't know what element or code that makes the box stay where they are like a menu bar despite many attempts of finding, so any help would be appreciated! Thank you!

So far, since I'm a beginner in React, my problem is that the online examples I refer to are written in a single file using 'class App', but what I'm trying to do is to have separate components, and I don't know how to convert the code properly.

My app includes index.js, App.js, and the components:\

  • Card.js

import React from "react";
    
function Card(props) {
  const dragStart = (e) => {
    const target = e.target;
    e.dataTransfer.dropEffect = "move";
    e.dataTransfer.setData("card_id", target.id);

    setTimeout(() => {
      target.style.display = "none";
    }, 0);
  };

  const dragOver = (e) => {
    e.stopPropagation();
    // e.dataTransfer.dropEffect = "copy";
  };

  return (
    <div
      id={props.id}
      className={props.className}
      draggable={props.draggable}
      onDragStart={dragStart}
      onDragOver={dragOver}
    >
      {props.children}
    </div>
  );
}

export default Card;

  • Board.js (the black box)

import React from "react";

function Board(props) {
  const drop = (e) => {
    e.preventDefault();
    const card_id = e.dataTransfer.getData("card_id");

    const card = document.getElementById(card_id);
    card.style.display = "block";

    e.target.appendChild(card);
  };

  const dragOver = (e) => {
    e.preventDefault();
  };

  return (
    <div
      id={props.id}
      className={props.className}
      onDrop={drop}
      onDragOver={dragOver}
    >
      {props.children}
    </div>
  );
}

export default Board;

  • Menu.js (the pink box)

import React from "react";
import Card from "./Card";

function Menu(props) {
  
  const dragOver = (e) => {
    e.preventDefault();
  };

  return (
    <div id={props.id} className={props.className} onDragOver={dragOver}>
      {props.children}
    </div>
  );
}

export default Menu;

  • My App.js is currently like this:

import React, { useState } from "react";
import Board from "./components/Board";
import Card from "./components/Card";
import Menu from "./components/Menu";

function App() {
  const [card_list, setList] = useState([
    { id: "card-1", value: "A" },
    { id: "card-2", value: "B" },
    { id: "card-3", value: "C" },
  ]);
  return (
    <div className="flexbox">
      <Menu id="menu-1" className="menu">
        {card_list.map((item) => {
          return (
            <Card
              key={item.id}
              value={item.value}
              id={item.id}
              className="card"
              draggable="true"
            >
              <p> {item.value}</p>
            </Card>
          );
        })}
      </Menu>

      <Board id="board-2" className="board">
        <Card id="card-other" className="card">
          <p> Card two </p>
        </Card>
      </Board>
    </div>
  );
}

export default App;

And index.js is nothing but:

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);

1 Answers
Related