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

拖拽功能异常:拖拽框无法落入目标列

React周历组件拖拽落点错误修复方案

问题描述

我基于React开发了一个周历组件,展示效果如下:
周历展示效果

当将可拖拽盒子从一个日期拖至另一日期的目标列时,例如把“Morooka”从周二9号拖到周日7号的第8列,最终它会落入第1列;从9号第1列拖到10号第6列,也会出现同样的落点错误。期望拖拽盒能落在释放位置对应的列,但目前所有拖拽操作都默认落入第1列。尝试在drop事件中打印信息,控制台能正确识别目标列、日期和时间段,但实际落点仍不正确。

问题根源

代码存在两个核心问题导致落点错误:

  • 渲染数据源不匹配:generateCalendar中渲染拖拽盒时,依赖的是原始的orderData.order而非更新后的calendarData,新拖拽的项会被放到数组末尾,渲染时自然落到第一列。
  • 状态未同步更新:handleDrop仅更新了calendarData,但没有同步更新父组件传入的orderData,而界面渲染逻辑依赖orderData,导致新位置无法正确展示。
  • 日期处理Bug:设置月份时直接传入字符串类型的月份值,Date.setMonth需要的是0起始的数字,会导致日期计算错误。

修复方案

1. 修正渲染数据源

在generateCalendar函数中,将ordersForDay的数据源改为calendarData,同时调整过滤逻辑匹配数据结构:

// 替换原有的ordersForDay过滤逻辑
const ordersForDay = calendarData.filter((order) => {
  const orderDate = new Date(order.day).getDate();
  return orderDate === parseInt(dayOfMonth);
});

2. 同步更新父组件状态

在handleDrop函数末尾,同时更新calendarData和orderData:

// 替换原有的setCalendarData调用
setCalendarData(newOrderData);
setOrderData({ ...orderData, order: newOrderData });

3. 修复日期处理逻辑

调整handleDrop中的日期生成代码,修复月份的数字转换问题:

const handleDrop = (e, timeSlotIndex, dayOfMonth, year, month) => {
  e.preventDefault();
  e.stopPropagation();
  
  // 保留原时间部分,仅更新日期
  const originalDate = new Date(changeData.OrderDate);
  // 注意:month是1起始,Date构造函数需要0起始的月份,所以减1
  const newDate = new Date(year, month - 1, dayOfMonth, 
    originalDate.getHours(), originalDate.getMinutes(), originalDate.getSeconds());

  // 生成更新后的拖拽项
  const updatedOrder = {
    ...changeData,
    OrderDate: newDate.toISOString(),
    RequiredDateAndTime: newDate.toISOString(),
    timeSlot: `${timeSlotIndex + 1}`
  };

  // 生成新的数据集:移除旧项,添加更新后的项
  const newOrderData = orderData.order
    .filter(item => item !== changeData)
    .concat(updatedOrder);

  // 同步更新状态
  setCalendarData(newOrderData);
  setOrderData({ ...orderData, order: newOrderData });
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 19:54:54