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

react-native-calendars的CalendarList触发ScrollToIndex越界报错如何解决?

问题根因

react-native-calendars的CalendarList组件的pastScrollRange、futureScrollRange属于初始化仅生效属性,组件首次挂载时会根据这两个值计算可渲染的月份列表、对应索引范围,后续异步更新这两个属性不会触发组件重新计算索引范围。
你当前的逻辑中,初始渲染时pastScrollRange取值为useState的默认值,后续useEffect异步更新该值时,组件内部已经完成了首次索引范围计算,若更新后的pastScrollRange大于初始值,内部滚动逻辑触发时就会出现索引越界报错。
你手动写死setShowPrevMonth(1)不报错的原因是最终pastScrollRange稳定为1,和初始默认值一致时不会触发范围不匹配的问题;若初始默认值设为0,首次计算的索引范围只有0~0,后续异步更新为1时来不及同步索引范围,就会触发报错。

解决方案

方案1:绑定key强制组件重新初始化

给CalendarList绑定关联可滚动范围的key属性,当pastScrollRange、futureScrollRange或起止日期变化时,组件会重新挂载,用最新的范围值初始化索引:

<CalendarList
  // key值绑定所有影响滚动范围的变量
  key={`cal-${startDateToBeShown}-${endDateToBeShown}-${showPrevMonth}-${showNextMonth}`}
  ref={calendarRef}
  current={today}
  calendarHeight="auto"
  theme={calTheme}
  firstDay={1}
  dayComponent={generateDayComponent}
  monthFormat={'MMMM'}
  hideExtraDays={true}
  markedDates={formattedMergedDays}
  futureScrollRange={showNextMonth}
  pastScrollRange={showPrevMonth}
  maxDate={endDateToBeShown}
  scrollEnabled={true}
/>

方案2:等待范围计算完成再渲染组件

新增状态控制组件渲染时机,等useEffect完成滚动范围计算后再渲染CalendarList,避免初始值和最终值不一致的问题:

const [showNextMonth, setShowNextMonth] = useState<number>(1)
const [showPrevMonth, setShowPrevMonth] = useState<number>(1)
// 新增计算完成状态
const [rangeReady, setRangeReady] = useState<boolean>(false)

useEffect(() => {
  const prevRange = moment(today).month() + 1 > moment(startDateToBeShown).month() + 1 ? 1 : 0
  const nextRange = moment(today).month() + 1 < moment(endDateToBeShown).month() + 1 ? 1 : 0
  setShowPrevMonth(prevRange)
  setShowNextMonth(nextRange)
  // 标记计算完成
  setRangeReady(true)
}, [startDateToBeShown, endDateToBeShown])

// 计算完成前不渲染CalendarList
if (!rangeReady) return null

return (
  <CalendarList
    ref={calendarRef}
    current={today}
    calendarHeight="auto"
    theme={calTheme}
    firstDay={1}
    dayComponent={generateDayComponent}
    monthFormat={'MMMM'}
    hideExtraDays={true}
    markedDates={formattedMergedDays}
    futureScrollRange={showNextMonth}
    pastScrollRange={showPrevMonth}
    maxDate={endDateToBeShown}
    scrollEnabled={true}
  />
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 06:45:00