如何将React DnD与React FullCalendar集成,设置日期单元格为拖放目标?
Hey there! Let's get your React DnD setup working with FullCalendar, turning every date cell into a drop target. I'll build this out using your existing React DnD code as a base, and adapt it to work with the FullCalendar React wrapper you're using.
Step 1: Create a Reusable Drop Target Component for Calendar Cells
First, let's make a component that wraps a calendar cell and turns it into a React DnD drop target—similar to your existing Box.js, but tailored to hold calendar date data.
Create DropableDayCell.js:
import React from 'react'; import { DropTarget } from 'react-dnd'; import { ItemTypes } from './Card'; // Reuse your existing ItemTypes const dayCellTarget = { canDrop(props) { // Add any logic here if you need to restrict drops on certain dates return true; // Allow all drops for this example }, drop(props, monitor) { // Access the dropped item and the cell's date const droppedItem = monitor.getItem(); console.log(`Dropped item on date: ${props.dateStr}`); // Add your custom logic here (e.g., save to state, create a calendar event) } }; function collect(connect, monitor) { return { connectDropTarget: connect.dropTarget(), isOver: monitor.isOver(), canDrop: monitor.canDrop() }; } const DropableDayCell = ({ connectDropTarget, isOver, canDrop, children, dateStr }) => { // Style cell to show drop state (optional but improves UX) const cellStyle = { backgroundColor: isOver && canDrop ? '#a5d6a7' : 'transparent', width: '100%', height: '100%', padding: '8px' }; return connectDropTarget( <div style={cellStyle}> {children} {/* Renders the original calendar cell content (day number) */} </div> ); }; export default DropTarget(ItemTypes.CARD, dayCellTarget, collect)(DropableDayCell);
Step 2: Configure FullCalendar to Use the Custom Drop Target Cell
Next, update your FullCalendar component to use the dayCellContent prop (supported by the fullcalendar-reactwrapper) to replace the default cell with our DropableDayCell.
Create CalendarWithDnD.js:
import React from 'react'; import FullCalendar from 'fullcalendar-reactwrapper'; import DropableDayCell from './DropableDayCell'; const CalendarWithDnD = () => { const handleDayCellContent = (info) => { // Pass the cell's date to our drop target component return ( <DropableDayCell dateStr={info.date.toISOString()}> {info.dayNumberText} {/* Keep the original day number display */} </DropableDayCell> ); }; return ( <FullCalendar id="calendar" header={{ left: 'prev,next today', center: 'title', right: 'month,agendaWeek,agendaDay' }} defaultView="month" dayCellContent={handleDayCellContent} // Override default cell rendering events={[]} // Add your calendar events here if needed /> ); }; export default CalendarWithDnD;
Step 3: Update Your Root Component to Include the Calendar
Adjust your existing simpleDrag.js to include the new calendar component, keeping your draggable Card intact:
import React, { Component } from 'react'; import { DragDropContext } from 'react-dnd'; import HTML5Backend from 'react-dnd-html5-backend'; import Card from './Card'; // Fixed import casing for consistency import CalendarWithDnD from './CalendarWithDnD'; class SimpleDrag extends Component { render() { return ( <div style={{ display: 'flex', gap: '20px', padding: '20px' }}> <Card /> {/* Your existing draggable card */} <CalendarWithDnD /> {/* The calendar with drop-enabled cells */} </div> ); } } export default DragDropContext(HTML5Backend)(SimpleDrag);
Key Notes:
- Reuse Item Types: We're using your existing
ItemTypes.CARDto ensure the drag source and drop targets are compatible. - Custom Drop Logic: In the
dropmethod ofDropableDayCell, you can access both the dragged item and the target date—use this to build your desired functionality (like creating a calendar event on the dropped date). - Visual Feedback: The cell styling gives users clear cues when an item can be dropped on a cell, which makes the interaction more intuitive.
- FullCalendar Compatibility: The
dayCellContentprop is the standard way to override cell rendering in the FullCalendar React wrapper—adjust props or styling based on your specific version if needed.
内容的提问来源于stack exchange,提问作者Alexander Solonik

