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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 14:15:05