ReactJS看板板拖放,无需使用外部库

siv3szwd  于 2022-12-26  发布在  React
关注(0)|答案(1)|浏览(127)
    • bounty将在7天后过期**。回答此问题的人有资格获得+50的声望奖励。Europa希望吸引更多人关注此问题。

我正在ReactJS中创建看板。所有阶段都存储为JSON,包含各自的任务。我希望能够将任务拖放到给定阶段标题,以便将其从一个阶段移动到另一个阶段。
这是我的看板:

当我将任务拖放到标题上时,我无法获得正确的阶段。我尝试记录它,但为常量handleOnDragOver提供的数据只是"未定义":
DragAndDropDemo() :: handleOnDragOver() :: e.target.name=undefined e.target.value=undefined
ReactJS代码:

import { useEffect, useState } from "react";

export function DragAndDropDemo() {

  /* Stages with tasks */
  const [stages, setStages] = useState([                      
    {
        name: "todo", 
        bgcolor: "green",
        tasks: [
            {name: "Integrate Slack"}
        ]
    },
    {
        name: "wip", 
        bgcolor: "yellow",
        tasks: [
            {name: "Learn Angular"},
            {name: "React"}
        ]
    },                        
    {
        name: "complete", 
        bgcolor: "orange",
        tasks: [
            {name: "Vue"}
        ]
    }                
  ]);

  /* Handle Drag and Drop */
  const handleOnDragStart = e => {
    console.log("DragAndDropDemo() :: handleOnDragStart() :: e.target.name="  + e.target.name + " e.target.value="  + e.target.value)
    
  };
  const handleOnDragOver = e => {
    console.log("DragAndDropDemo() :: handleOnDragOver() :: e.target.name="  + e.target.name + " e.target.value="  + e.target.value)
  };
  const handleOnDrop = e => {
    console.log("DragAndDropDemo() :: handleOnDrop() :: e.target.name="  + e.target.name + " e.target.value="  + e.target.value)
  };

  

  return (
    <div>
    {stages.map((stage_item, stage_index) => {
        const tasks = stage_item["tasks"];
        return (
          <div key={stage_index} style={{backgroundColor: stage_item.bgcolor, float: "left", border: "#000 1px solid"}}>
            <h2 id={stage_item.name} className="droppable" onDragOver={handleOnDragOver} onDrop={handleOnDrop} style={{border: "#000 1px dashed", padding: "10px", margin: "1px"}}>{stage_item.name}</h2>

            
            {tasks.map((task_item, task_index) => {
                return(
                <div key={task_index} onDragStart={handleOnDragStart} draggable className="draggable"  style={{backgroundColor: "white", border: "#ccc 1px solid", padding: "10px"}}>
                    <p>{task_item.name}</p>
                </div>
                );
            })}
          </div>
        )
      })}
      <div style={{clear: "both"}}></div>

    </div>
    );
}
  
export default DragAndDropDemo;
6mzjoqzu

6mzjoqzu1#

您应该在start事件上使用dataTransfer属性:https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API#define_the_drags_data
例如,要将被拖动元素的id传递给drop事件,可以在start事件处理程序中使用dataTransfer对象的setData函数,然后在drop事件处理程序中使用getData,如下所示:

import { useCallback, useEffect, useState } from "react";

export function DragAndDropDemo() {
  /* Stages with tasks */
  const [stages, setStages] = useState([
    {
      name: "todo",
      bgcolor: "green",
      tasks: [{ name: "Integrate Slack" }]
    },
    {
      name: "wip",
      bgcolor: "yellow",
      tasks: [{ name: "Learn Angular" }, { name: "React" }]
    },
    {
      name: "complete",
      bgcolor: "orange",
      tasks: [{ name: "Vue" }]
    }
  ]);

  /* Handle Drag and Drop */
  const handleOnDragStart = (e) => {
    console.log("start", e);
    e.dataTransfer.setData("application/my-app", e.target.id);

    console.log(
      "DragAndDropDemo() :: handleOnDragStart() :: e.target.name=" +
        e.target.name +
        " e.target.value=" +
        e.target.value
    );
  };

  const handleOnDragOver = (e) => {
    e.preventDefault();
    e.dataTransfer.dropEffect = "move";

    console.log(
      "DragAndDropDemo() :: handleOnDragOver() :: e.target.name=" +
        e.target.name +
        " e.target.value=" +
        e.target.value
    );
  };

  const handleOnDrop = (e) => {
    e.preventDefault();

    const data = e.dataTransfer.getData("application/my-app");
    console.log("data", data);

    console.log(
      "DragAndDropDemo() :: handleOnDrop() :: e.target.name=" +
        e.target.name +
        " e.target.value=" +
        e.target.value
    );
  };

  return (
    <div>
      {stages.map((stage_item, stage_index) => {
        const tasks = stage_item["tasks"];
        return (
          <div
            key={stage_index}
            style={{
              backgroundColor: stage_item.bgcolor,
              float: "left",
              border: "#000 1px solid"
            }}
          >
            <h2
              id={stage_item.name}
              className="droppable"
              onDragOver={(e) => handleOnDragOver(e)}
              onDrop={handleOnDrop}
              style={{
                border: "#000 1px dashed",
                padding: "10px",
                margin: "1px"
              }}
            >
              {stage_item.name}
            </h2>

            {tasks.map((task_item, task_index) => {
              return (
                <div
                  key={task_index}
                  onDragStart={handleOnDragStart}
                  draggable
                  id={task_item.name}
                  className="draggable"
                  style={{
                    backgroundColor: "white",
                    border: "#ccc 1px solid",
                    padding: "10px"
                  }}
                >
                  <p>{task_item.name}</p>
                </div>
              );
            })}
          </div>
        );
      })}
      <div style={{ clear: "both" }}></div>
    </div>
  );
}

export default DragAndDropDemo;

相关问题