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

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; 

解决方案

问题原因

  1. 组件类型误用:eventWrapper的作用是包裹默认事件组件,而非直接替换事件内容。自定义事件内容应该使用event组件类型。
  2. 样式未继承:自定义组件没有继承react-big-calendar默认事件的布局样式(如高度、宽度、内边距),导致无法填满单元格。
  3. 手动高度冲突:calculateEventStyle手动设置高度,会覆盖组件根据事件时长自动计算的高度,破坏布局逻辑。

修复步骤

  1. 替换组件类型:将components配置中的eventWrapper改为event。
  2. 继承默认样式:给自定义事件容器添加默认事件类名rbc-event,确保布局规则生效。
  3. 移除手动高度计算:保留自定义背景色逻辑即可,让组件自动适配事件时长。

修改后的代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 00:22:32