导航返回时如何恢复React Native FlatList的原有滚动位置?
问题根因
- 你将
numbersOfItem存储在组件本地state中,默认值写死为20,当跳转到商品详情页后如果列表页组件被销毁(比如导航配置问题、页面被系统回收),返回时组件重新挂载,numbersOfItem就会重置为20,加载的列表长度回到20条,FlatList自然会滚动到对应位置。 - 本地state
itemList仅在组件初始化时同步了redux中的productList,后续redux中列表数据更新后没有同步到本地state,数据源匹配异常也会导致滚动位置计算错误。 - FlatList的
keyExtractor用了数组下标作为唯一标识,数据更新时下标对应的商品项会发生变化,FlatList无法正确定位元素位置,也会引发滚动偏移。
修复方案
- 将分页数量
numbersOfItem存储到redux的productReducer中,不要存在组件本地state,就算组件重新挂载也能读取到上次加载到的分页值,不会重置为20。 - 移除本地的
itemListstate,直接将redux中的productList作为FlatList的数据源,避免多数据源同步问题。 - 修改
keyExtractor,使用商品的唯一ID作为key,保证FlatList能正确识别每个元素的位置。 - 如果你用的是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
相关产品推荐
相关产品推荐

