You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React中实现任务拖拽至react-big-calendar?

任务列表到react-big-calendar的拖拽实现方案

1. 确认日历的拖拽基础配置

首先确保react-big-calendar的withDragAndDrop高阶组件正确包裹日历,并开启日历的droppable属性,同时预留拖拽相关事件处理函数:

import { Calendar, withDragAndDrop } from 'react-big-calendar';
import 'react-big-calendar/lib/css/react-big-calendar.css';

const DnDCalendar = withDragAndDrop(Calendar);

const Dashboard = () => {
  const [events, setEvents] = useState([]);
  const [tasks, setTasks] = useState([
    { id: 1, title: '优化用户界面', description: '调整页面布局' }
  ]);

  // 后续实现拖拽处理函数

  return (
    <div className="dashboard-container">
      <DnDCalendar
        events={events}
        startAccessor="start"
        endAccessor="end"
        droppable // 允许接收外部拖拽
        onDragOver={handleDragOver}
        onDrop={handleDrop}
        // 其他日历配置项
      />
      <div className="task-list">
        {tasks.map(task => (
          <DraggableEvent key={task.id} task={task} />
        ))}
      </div>
    </div>
  );
};

2. 改造任务组件为可拖拽元素

给任务组件添加原生draggable属性,并在拖拽开始时传递任务数据:

const DraggableEvent = ({ task }) => {
  const handleDragStart = (e) => {
    // 将任务序列化为JSON字符串传递
    e.dataTransfer.setData('application/json', JSON.stringify(task));
    e.dataTransfer.effectAllowed = 'copy'; // 设置拖拽行为类型
  };

  return (
    <div
      draggable
      onDragStart={handleDragStart}
      className="task-item"
      style={{ padding: '8px', border: '1px solid #eee', margin: '4px 0', cursor: 'move' }}
    >
      <h4>{task.title}</h4>
      <p>{task.description}</p>
    </div>
  );
};

3. 实现日历的拖拽接收逻辑

在Dashboard组件中编写handleDragOver和handleDrop函数,处理拖拽到日历后的事件创建:

const handleDragOver = (e) => {
  e.preventDefault(); // 必须阻止默认行为,否则drop事件无法触发
  e.dataTransfer.dropEffect = 'copy';
};

const handleDrop = (e, slotInfo) => {
  e.preventDefault();
  // 解析拖拽过来的任务数据
  const draggedTask = JSON.parse(e.dataTransfer.getData('application/json'));
  
  // 基于日历插槽信息创建新事件,默认设置为1小时时长
  const newCalendarEvent = {
    id: Date.now(), // 生成唯一ID
    title: draggedTask.title,
    description: draggedTask.description,
    start: slotInfo.start,
    end: new Date(slotInfo.start.getTime() + 60 * 60 * 1000) // 1小时后结束
  };

  // 更新日历事件列表
  setEvents([...events, newCalendarEvent]);
  // 可选:从任务列表移除已拖拽的任务
  setTasks(tasks.filter(t => t.id !== draggedTask.id));
};

4. 核心注意事项

  • handleDragOver中必须调用e.preventDefault(),否则浏览器会阻止drop事件触发。
  • 拖拽数据使用application/json类型,避免和其他拖拽行为冲突。
  • 可以根据需求调整事件的默认时长,或者让用户在拖拽前配置任务时长。
  • 确保日历的startAccessor和endAccessor与你创建的事件字段一致。

内容的提问来源于stack exchange,提问作者Soumaya Guenaguen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 16:31:15