React Native中Flatlist触发onEndReached时滚动卡顿问题如何解决?
React Native FlatList上拉加载滚动冻结优化方案
核心优化点
- 修复loadMoreData的低效去重逻辑
你当前使用[...new Set([...prevItems, ...testItem])]的写法,当数组长度到2000条以上时,每次触发加载都要全量展开数组两次,还要遍历全量数据做Set去重,会直接占满JS线程导致冻结。如果你的testItem每次只有1个元素,直接判断目标元素是否存在再追加即可,避免全量遍历:
const loadMoreData = () => { setData(prevItems => { // 替换为你item中实际的唯一标识字段做存在性判断 const isExist = prevItems.some(item => item.id === testItem[0].id) if (isExist) return prevItems return [...prevItems, testItem[0]] }) }
如果确实需要全量去重,把逻辑放到交互空闲回调中执行,避免阻塞滚动线程:
import { InteractionManager } from 'react-native' const loadMoreData = () => { InteractionManager.runAfterInteractions(() => { setData(prevItems => [...new Set([...prevItems, ...testItem])]) }) }
- 替换错误的keyExtractor实现
你当前用数组下标作为key,当追加新数据时所有列表项的key都会重新计算,FlatList会误以为全部元素需要重渲染,2000条量级的重渲染开销直接导致卡顿。必须用item本身的唯一标识作为key:
// 替换为你item中实际的唯一标识字段,比如id、uuid keyExtractor={(item) => item.id.toString()}
- 删除冗余的extraData配置
你已经把data作为FlatList的data属性传入,extraData仅需要在触发更新的变量不在data中时传入,当前extraData={data}的写法会额外触发一次FlatList全量重渲染检查,直接删除该行即可。
- 优化列表项组件渲染性能
- 删除renderItem外层冗余的空
<></>Fragment节点,减少不必要的节点嵌套 - 给
InventoryItem、HoldItem、Swipeable相关的列表项组件都套上React.memo,通过浅层props对比避免不必要的重渲染:
// 示例:InventoryItem组件定义时包裹memo const InventoryItem = React.memo(({item}) => { // 原有组件逻辑 })
- 若Swipeable的右滑菜单不是默认展示状态,可以改成用户首次触发滑动时再初始化菜单内容,减少初始渲染开销。
内容的提问来源于stack exchange,提问作者nick
相关产品推荐
相关产品推荐

