React-Big-Calendar自定义事件显示样式异常求助
问题
使用react-big-calendar开发日历组件时,希望修改事件容器仅展示事件标题,但自定义EventDisplay组件后,事件容器样式被破坏,无法填满预留的单元格;即使删除calculateEventStyle函数,样式问题仍存在,无报错仅显示异常。
相关代码如下:
import { Calendar, momentLocalizer } from "react-big-calendar"; import "react-big-calendar/lib/css/react-big-calendar.css"; import moment from "moment"; import "../Css/Calendar.css"; import axios from "axios"; import { useState, useEffect } from "react"; // 补充原代码缺失的导入 var endpoint = "http://localhost:5000/tasks"; const localizer = momentLocalizer(moment); const messages = { previous: "←", next: "→", today: "Today", month: "Month", week: "Week", day: "Day", date: "Date", time: "Time", }; const WeeklyCalendar: React.FC = () => { const startingHour = 8; const timeGutterFormat = "H:mm"; const [events, setEvents] = useState([]); const localUser = localStorage.getItem("user"); const EventDisplay = ({ event }) => { return ( <div className="custom-event" style={event.style}> {event.title} </div> ); }; const calculateEventStyle = (event) => { const durationInMinutes = (event.end - event.start) / (1000 * 60); const height = durationInMinutes * 2; // Adjust this multiplier as needed return { style: { height: `${height}px`, backgroundColor: "black", }, }; }; useEffect(() => { axios .get("/tasks", { params: { user: localUser, }, }) .then((response) => { const tasks = response.data; const formattedEvents = tasks.map((task: any) => ({ title: task.title, start: new Date(task.start), end: new Date(task.end), })); setEvents(formattedEvents); }) .catch((error) => { console.error("Error fetching data:", error); }); }, []); return ( <div className="weekly-calendar-container"> <Calendar localizer={localizer} defaultView="week" startAccessor="start" endAccessor="end" min={new Date().setHours(startingHour, 0, 0, 0)} style={{ height: 600, width: 1000 }} events={events} formats={{ timeGutterFormat, }} messages={messages} components={{ eventWrapper: EventDisplay, }} eventPropGetter={calculateEventStyle} /> </div> ); }; export default WeeklyCalendar;
解决方案
问题原因
- 组件类型误用:
eventWrapper的作用是包裹默认事件组件,而非直接替换事件内容。自定义事件内容应该使用event组件类型。 - 样式未继承:自定义组件没有继承react-big-calendar默认事件的布局样式(如高度、宽度、内边距),导致无法填满单元格。
- 手动高度冲突:
calculateEventStyle手动设置高度,会覆盖组件根据事件时长自动计算的高度,破坏布局逻辑。
修复步骤
- 替换组件类型:将
components配置中的eventWrapper改为event。 - 继承默认样式:给自定义事件容器添加默认事件类名
rbc-event,确保布局规则生效。 - 移除手动高度计算:保留自定义背景色逻辑即可,让组件自动适配事件时长。
修改后的代码
import { Calendar, momentLocalizer } from "react-big-calendar"; import "react-big-calendar/lib/css/react-big-calendar.css"; import moment from "moment"; import "../Css/Calendar.css"; import axios from "axios"; import { useState, useEffect } from "react"; var endpoint = "http://localhost:5000/tasks"; const localizer = momentLocalizer(moment); const messages = { previous: "←", next: "→", today: "Today", month: "Month", week: "Week", day: "Day", date: "Date", time: "Time", }; const WeeklyCalendar: React.FC = () => { const startingHour = 8; const timeGutterFormat = "H:mm"; const [events, setEvents] = useState([]); const localUser = localStorage.getItem("user"); // 自定义事件组件,继承默认样式并仅展示标题 const CustomEvent = ({ event }) => { return ( <div className="rbc-event custom-event"> <span className="rbc-event-content">{event.title}</span> </div> ); }; // 仅自定义背景色,不手动控制高度 const eventPropGetter = (event) => { return { style: { backgroundColor: "black", }, }; }; useEffect(() => { axios .get("/tasks", { params: { user: localUser, }, }) .then((response) => { const tasks = response.data; const formattedEvents = tasks.map((task: any) => ({ title: task.title, start: new Date(task.start), end: new Date(task.end), })); setEvents(formattedEvents); }) .catch((error) => { console.error("Error fetching data:", error); }); }, [localUser]); // 补充依赖项,确保localUser变化时重新请求 return ( <div className="weekly-calendar-container"> <Calendar localizer={localizer} defaultView="week" startAccessor="start" endAccessor="end" min={new Date().setHours(startingHour, 0, 0, 0)} style={{ height: 600, width: 1000 }} events={events} formats={{ timeGutterFormat, }} messages={messages} components={{ event: CustomEvent, // 替换为正确的event组件 }} eventPropGetter={eventPropGetter} /> </div> ); }; export default WeeklyCalendar;
可选样式优化
若需进一步调整事件显示效果,可在Calendar.css中添加:
.custom-event { display: flex; align-items: center; padding: 0 4px; } .custom-event .rbc-event-content { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
内容的提问来源于stack exchange,提问作者Alessia Volpi
相关产品推荐
相关产品推荐

