React Native中ScrollView停止滚动或滚动到底部时触发API数据请求方案
React Native ScrollView 滚动触发API拉取实现方案
ScrollView 本身自带官方回调事件,无需引入第三方依赖即可实现需求,以下是完整实现逻辑和代码:
核心实现思路
你需要的两个触发条件可以分别通过 ScrollView 自带的两个回调实现:
- 滚动到底部触发:通过
onScroll回调拿到滚动位置、内容总高度、可视区域高度三个参数,计算是否触达底部 - 滚动停止触发:直接用
onMomentumScrollEnd回调,该事件会在滚动惯性完全停止时自动触发
完整代码示例
import React, { useState, useCallback } from 'react'; import { ScrollView, View, Text, ActivityIndicator, StyleSheet } from 'react-native'; const AutoLoadScroll = () => { // 存储接口返回的列表数据 const [dataList, setDataList] = useState([]); // 加载状态锁,避免重复发起请求 const [isLoading, setIsLoading] = useState(false); // 分页参数,可根据你的接口规则调整 const [pageNum, setPageNum] = useState(1); // API拉取逻辑,替换为你自己的业务接口 const fetchApiData = useCallback(async () => { if (isLoading) return; setIsLoading(true); try { const res = await fetch(`你的接口地址?page=${pageNum}&size=10`); const result = await res.json(); // 拼接新老数据 setDataList(prevList => [...prevList, ...result.data.list]); setPageNum(prev => prev + 1); } catch (err) { console.log('接口请求报错:', err); } finally { setIsLoading(false); } }, [isLoading, pageNum]); // 滚动监听,判断是否触达底部 const handleScroll = useCallback((event) => { const { contentOffset, contentSize, layoutMeasurement } = event.nativeEvent; // 底部触发阈值,单位px,可自行调整,提前触发加载体验更好 const bottomThreshold = 20; const isReachBottom = contentOffset.y + layoutMeasurement.height >= contentSize.height - bottomThreshold; if (isReachBottom) { fetchApiData(); } }, [fetchApiData]); // 滚动停止时触发拉取 const handleScrollStop = useCallback(() => { // 如果不需要滚动停止就拉取,直接删掉这个回调即可 fetchApiData(); }, [fetchApiData]); return ( <ScrollView style={styles.scrollContainer} onScroll={handleScroll} onMomentumScrollEnd={handleScrollStop} // 滚动事件触发频率,单位ms,16是比较平衡性能和灵敏度的数值 scrollEventThrottle={16} > {/* 你的列表内容 */} {dataList.map((item, index) => ( <View key={index} style={styles.itemCard}> <Text>{item.content}</Text> </View> ))} {/* 加载中提示 */} {isLoading && <ActivityIndicator style={styles.loadingTip} size="small" color="#666" />} </ScrollView> ) } const styles = StyleSheet.create({ scrollContainer: { flex: 1 }, itemCard: { padding: 16, borderBottomWidth: 1, borderBottomColor: '#f5f5f5' }, loadingTip: { paddingVertical: 20 } }) export default AutoLoadScroll;
注意事项
- 如果你的需求是只有停止滚动且滚动到底部时才触发拉取,可以把底部判断逻辑放到
handleScrollStop里,不需要两个回调都调用请求方法 scrollEventThrottle不要设置过小,否则会导致滚动事件触发过于频繁,增加性能损耗- 可以额外增加
hasMore状态记录是否还有更多数据,判断无数据后不再触发请求,减少无效接口调用 - 如果是长列表场景,优先使用
FlatList组件,自带onEndReached回调,不需要手动计算滚动位置,性能也更优
内容的提问来源于stack exchange,提问作者Manish kumar
相关产品推荐
相关产品推荐

