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

导航返回时如何恢复React Native FlatList的原有滚动位置?

问题根因

  • 你将numbersOfItem存储在组件本地state中,默认值写死为20,当跳转到商品详情页后如果列表页组件被销毁(比如导航配置问题、页面被系统回收),返回时组件重新挂载,numbersOfItem就会重置为20,加载的列表长度回到20条,FlatList自然会滚动到对应位置。
  • 本地stateitemList仅在组件初始化时同步了redux中的productList,后续redux中列表数据更新后没有同步到本地state,数据源匹配异常也会导致滚动位置计算错误。
  • FlatList的keyExtractor用了数组下标作为唯一标识,数据更新时下标对应的商品项会发生变化,FlatList无法正确定位元素位置,也会引发滚动偏移。

修复方案

  1. 将分页数量numbersOfItem存储到redux的productReducer中,不要存在组件本地state,就算组件重新挂载也能读取到上次加载到的分页值,不会重置为20。
  2. 移除本地的itemList state,直接将redux中的productList作为FlatList的数据源,避免多数据源同步问题。
  3. 修改keyExtractor,使用商品的唯一ID作为key,保证FlatList能正确识别每个元素的位置。
  4. 如果你用的是React Navigation,可在列表页的路由配置中开启保活(不同版本配置略有差异),跳转到详情页时不销毁列表页组件,本地状态不会丢失。

修改后代码示例

// 从redux中读取分页数量和商品列表
const { productList, numbersOfItem } = useSelector(state => state.productReducer);

const handleLoadMoreData = async () => {
  setLoadingMoreData(true);
  try {
    const requestNumber = numbersOfItem + 20;
    // 直接在dispatch的action里更新redux中的numbersOfItem,不需要本地state存储
    await dispatch(
      fetchProductList(
        categoryTitle,
        subCategoryName,
        activeTab,
        requestNumber,
      ),
    );
  } catch {
    console.log('error');
  } finally {
    setLoadingMoreData(false);
  }
};

<FlatList
  data={productList}
  numColumns={2}
  nestedScrollEnabled
  columnWrapperStyle={styles.flatItemColumn}
  scrollEnabled
  scrollEventThrottle={16}
  snapToAlignment="start"
  decelerationRate={'fast'}
  showsHorizontalScrollIndicator={false}
  renderItem={renderIndividualItem}
  // 用商品唯一id作为key,不要用数组下标
  keyExtractor={(item) => String(item.id)}
  onEndReached={() => handleLoadMoreData()}
/>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 00:15:09