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

横向FlatList传入后端数据报scrollToIndex越界错误如何解决?

问题根因分析
  • 依赖数组缺失必要项:当前useEffect仅监听selectedPlaceId,未包含places、trips两个异步数据源,接口返回数据更新后不会重新触发执行逻辑,首次执行effect时后端数据尚未返回,places、trips均为空数组,此时计算出的索引不合法,且FlatList尚未完成数据渲染,调用滚动方法直接报错
  • 索引计算与滚动目标不匹配:index是从places数组计算得到,但FlatList绑定的数据源是trips,两个数组长度不一致时计算出的索引必然超出FlatList的合法范围,横向FlatList对滚动索引合法性校验比纵向更严格,因此仅横向场景触发报错
  • 缺少前置校验逻辑:调用scrollToIndex前未校验FlatList实例是否存在、数据源长度是否合法、索引是否在可用范围内,空数据场景直接调用方法触发报错
修复方案
  1. 补全useEffect依赖项,新增数据源非空、索引合法性校验
  2. 确保计算出的滚动索引匹配trips数组的长度范围,若需保持索引逻辑基于places,需保证两个数组长度、顺序完全一致,或单独基于trips计算滚动索引
  3. 新增FlatList渲染完成判断,避免在布局未完成时调用滚动方法
修改后参考代码
import { InteractionManager } from 'react-native';

useEffect(() => {
    // 先校验数据源是否加载完成、实例是否存在
    if (!places.length || !trips.length || !flatlist.current) return;

    const getIndex = (placeholder = 0) => {
        const index = places.findIndex(place => place.id === selectedPlaceId);
        // 额外校验索引不超过trips数组的最大合法值
        if (index === -1 || index >= trips.length) return placeholder;
        return index;
    };

    const index = getIndex();
    // 二次校验索引合法性
    if (index < 0 || index >= trips.length) return;

    // 等待交互和渲染完成后再执行滚动
    InteractionManager.runAfterInteractions(() => {
        flatlist.current?.scrollToIndex({
            index,
            animated: true,
            // 新增容错,找不到对应索引时自动滚动到就近位置
            fallback: true
        });
    })

    const selectedPlace = places[index];
    const region = {
        latitude: selectedPlace.coordinate.latitude,
        longitude: selectedPlace.coordinate.longitude,
        latitudeDelta: 0.8,
        longitudeDelta: 0.8
    }
    map.current?.animateToRegion(region);

// 补全所有依赖项
}, [selectedPlaceId, places, trips])


return (
    <FlatList
         ref={flatlist}
         data={trips}
         renderItem={({ item }) => <PostCarouselItem post={item} />}
         horizontal
         showsHorizontalScrollIndicator={false}
         snapToInterval={width - 70}
         snapToAlignment={"center"}
         decelerationRate={"fast"}
         viewabilityConfig={viewConfig.current}
         onViewableItemsChanged={onViewChanged.current}
         style={{ bottom: 10, left: 0, right: 0, position: "absolute", }}
         contentContainerStyle={{ marginHorizontal: cardWidth }}
         ListFooterComponent={<View style={{marginRight: (cardWidth * 2)}}/>}
         // 可选:数据加载完成后首次滚动兜底
         onContentSizeChange={() => {
             if (trips.length && flatlist.current && selectedPlaceId) {
                 const index = places.findIndex(place => place.id === selectedPlaceId);
                 if (index >=0 && index < trips.length) {
                     flatlist.current.scrollToIndex({index, fallback: true})
                 }
             }
         }}
    />
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 02:30:02