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

Flatlist触发onEndReached更新state时自动滚动至顶部问题

问题原因与解决方案

核心问题:FlatList 因组件重复挂载丢失滚动位置

当你触发onEndReached调用setPage更新状态时,Order组件会重渲染,此时renderScenes里的场景渲染函数(比如pending: () => <Pending .../>)会被重新创建,导致TabView认为这是一个全新的组件,会卸载旧的Pending组件并挂载新的实例——这直接导致FlatList重置到顶部,因为新挂载的FlatList没有保存之前的滚动状态。

具体修复步骤

  1. 稳定场景渲染函数的引用
    用useCallback包裹每个场景的渲染函数,确保组件重渲染时函数引用不变,避免TabView重复卸载/挂载子组件:
const Order = ({navigation}: any) => {
  // ... 其他状态和函数

  // 用useCallback包裹场景渲染函数
  const renderPending = useCallback(() => (
    <Pending
      loading={loading}
      orderData={orderData}
      onEndReached={handleEndReached}
    />
  ), [loading, orderData, handleEndReached]);

  const renderConfirmed = useCallback(() => (
    <Confirmed loading={loading} orderData={orderData} />
  ), [loading, orderData]);

  const renderAll = useCallback(() => (
    <All loading={loading} orderData={orderData} />
  ), [loading, orderData]);

  const renderScenes = {
    pending: renderPending,
    confirmed: renderConfirmed,
    all: renderAll,
  };

  // ... 其他代码
};
  1. 优化keyExtractor(可选但推荐)
    当前keyExtractor使用${item.id}-${index},如果分页加载时数据追加,index会变化,可能导致FlatList重新渲染部分项。建议直接用唯一的item.id作为key:
keyExtractor={(item) => item.id.toString()}
  1. 避免不必要的组件重渲染(可选)
    给Pending、Confirmed、All组件添加React.memo,减少不必要的重渲染:
const Pending = React.memo(({orderData, loading, onEndReached}: any) => {
  // 组件原有代码
});

补充说明

即使你还没调用API,setPage触发的组件重渲染已经足够让场景组件重新挂载,这就是滚动到顶部的根本原因。通过稳定组件引用,就能保留FlatList的滚动状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 00:52:35