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
相关产品推荐
相关产品推荐

