拖拽功能异常:拖拽框无法落入目标列
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
相关产品推荐
相关产品推荐

