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

React压缩错误#185求助:FullCalendar启用注释代码后报错

解决React-FullCalendar触发Minified React错误#185的问题

问题核心

错误#185对应的原始错误是Too many re-renders. React limits the number of renders to prevent an infinite loop.,即组件陷入了无限重渲染循环。从你注释的代码来看,问题出在eventsList状态更新与FullCalendar组件渲染的循环触发上。

触发原因

当你解除以下注释后:

  1. 启用eventsList状态管理日历事件
  2. 将events: eventsList传入FullCalendar配置
  3. 在API回调中调用setEventsList(list)更新状态

会形成如下循环:

  • eventsList更新 → FullCalendar组件重新渲染
  • FullCalendar渲染时触发datesSet回调 → 更新startDate/endDate状态
  • endDate变化触发useEffect → 调用getAllCalendarAppointmentsAction获取数据
  • API回调中再次调用setEventsList → 回到第一步,循环往复

另外,calendarOptions在组件每次渲染时都会重新创建新对象,即使eventsList没变化,也会导致FullCalendar重复接收新props,加剧重渲染问题。

解决方案

1. 用useMemo缓存日历配置对象

避免每次渲染都生成新的calendarOptions,只有当依赖项变化时才更新:

// 恢复eventsList状态
const [eventsList, setEventsList] = useState([])

// 用useMemo缓存calendarOptions
const calendarOptions = useMemo(() => ({
  navLinks: true,
  dayMaxEvents: 1,
  editable: false,
  ref: calendarRef,
  selectable: true,
  nowIndicator: true,
  eventOverlap: false,
  slotMinTime: '06:00:00',
  slotMaxTime: '23:30:00',
  stickyHeaderDates: true,
  initialView: 'timeGridWeek',
  stickyFooterScrollbar: true,
  schedulerLicenseKey: '0599384492-fcs-1678752810',
  events: eventsList, // 恢复使用eventsList
  plugins: [
    interactionPlugin,
    ScrollGridPlugin,
    dayGridPlugin,
    timeGridPlugin
  ],
  // 其余配置保持不变...
}), [isMobile, view, eventsList, provider_id]) // 添加上所有依赖项

2. 避免不必要的状态更新

在API回调中,先对比新生成的事件列表与当前eventsList,只有不同时才更新状态:

// 先引入lodash的isEqual(或自行实现浅比较逻辑)
import isEqual from 'lodash/isEqual'

// 在getAllCalendarAppointmentsAction的回调中修改:
callback: (res) => {
  let list = res.map((row) => {
    // 原有的事件转换逻辑保持不变
  })
  // 浅比较新列表与当前状态,不同才更新
  if (!isEqual(list, eventsList)) {
    setEventsList(list)
  }
}

3. 调整useEffect依赖项

如果success状态每次API调用都会触发变化,会导致useEffect重复执行,可以考虑移除success依赖,或者用ref跟踪是否需要重新获取数据:

// 替换原有的Appointments Action useEffect
const initialLoadRef = useRef(true)

useEffect(() => {
  if (endDate && !initialLoadRef.current) {
    dispatch(
      getAllCalendarAppointmentsAction({
        // 原配置不变
      })
    )
  }
  initialLoadRef.current = false
}, [endDate]) // 移除success依赖,仅在endDate变化时触发

额外优化

可以直接将API获取的事件数据通过FullCalendar的events函数传入,跳过state中转,从根源避免循环:

const calendarOptions = useMemo(() => ({
  // 其他配置不变
  events: (info, successCallback) => {
    if (!provider_id || !info.startStr || !info.endStr) return
    const start = info.startStr.split('T')[0]
    const end = info.endStr.split('T')[0]
    dispatch(
      getAllCalendarAppointmentsAction({
        offset: 0,
        limit: 100,
        startDate: start,
        endDate: end,
        providerId: provider_id,
        callback: (res) => {
          let list = res.map((row) => {
            // 原有的事件转换逻辑
          })
          successCallback(list)
        }
      })
    )
  },
  // 其余配置不变
}), [provider_id, isMobile, view])

这种方式让FullCalendar主动请求数据,无需通过state管理事件列表,彻底避免重渲染循环。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 22:45:01