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

React Native对接ExerciseDB API:limit参数失效,需实现下拉加载更多

解决ExerciseDB API分页加载问题及滚动加载更多实现

问题分析

你遇到的limit参数无效,是因为ExerciseDB API的/exercises端点需要配合offset参数实现分页,仅传limit不会生效;同时当前实现会直接覆盖现有数据,无法实现加载更多的追加逻辑。

修复步骤

1. 改造useFetch Hook,支持分页与数据追加

修改你的useFetch hook,增加偏移量状态、加载更多逻辑,并调整数据更新方式:

import { useState, useEffect } from "react";
import axios from "axios";

const useFetch = (endpoint, limit) => {
    const [data, setData] = useState([]);
    const [offset, setOffset] = useState(0);
    const [isLoading, setIsLoading] = useState(false);
    const [isLoadingMore, setIsLoadingMore] = useState(false);
    const [error, setError] = useState(null);
    const [hasMore, setHasMore] = useState(true);

    const options = {
        method: 'GET',
        url: `https://exercisedb.p.rapidapi.com/${endpoint}?limit=${limit}&offset=${offset}`,
        headers: {
            'X-RapidAPI-Key': API,
            'X-RapidAPI-Host': 'exercisedb.p.rapidapi.com'
        },
    };

    const fetchData = async (isLoadMore = false) => {
        if (isLoadMore) setIsLoadingMore(true);
        else setIsLoading(true);

        try {
            const response = await axios.request(options);
            // 加载更多时追加数据,初始加载时替换
            if (isLoadMore) {
                setData(prev => [...prev, ...response.data]);
                // 返回数据少于limit则标记无更多数据
                if (response.data.length < limit) setHasMore(false);
            } else {
                setData(response.data);
                setHasMore(response.data.length === limit);
            }
        } catch (error) {
            setError(error);
            alert('加载失败');
        } finally {
            if (isLoadMore) setIsLoadingMore(false);
            else setIsLoading(false);
        }
    }

    useEffect(() => {
        fetchData();
    }, [endpoint, limit, offset]);

    const loadMore = () => {
        if (hasMore && !isLoadingMore) {
            setOffset(prev => prev + limit);
        }
    }

    const refetch = () => {
        setOffset(0);
        setHasMore(true);
        fetchData();
    }

    return { data, isLoading, isLoadingMore, error, hasMore, loadMore, refetch };
}

export default useFetch;

2. 使用FlatList实现滚动加载更多

修改Searchworkouts组件,用FlatList替代普通View渲染列表,利用onEndReached触发加载更多:

import { View, Text, TouchableOpacity, ActivityIndicator, FlatList } from 'react-native'
import { useRouter } from 'expo-router'

import styles from './searchworkouts.style'
import { COLORS, SIZES } from '../../../constants'
import WorkoutCard from '../../common/cards/workout/WorkoutCard'

import useFetch from '../../../hook/useFetch';

const Searchworkouts = () => {
  const router = useRouter();

  const { data, isLoading, isLoadingMore, error, hasMore, loadMore } = useFetch('exercises', 10);

  const renderFooter = () => {
    if (!hasMore) return null;
    return (
      <View style={styles.loadingMoreContainer}>
        <ActivityIndicator size="small" color={COLORS.primary} />
      </View>
    );
  }

  return (
    <View style={styles.container}>
      <View style={styles.header}>
        <Text style={styles.headerTitle}>Workouts</Text>
        <TouchableOpacity>
          <Text style={styles.headerBtn}>Show all</Text>
        </TouchableOpacity>
      </View>

      {isLoading ? (
        <ActivityIndicator size="large" color={COLORS.primary} style={styles.loadingIndicator} />
      ) : error ? (
        <Text style={styles.errorText}>加载出错了</Text>
      ) : (
        <FlatList
          data={data}
          keyExtractor={(item) => item.id} // 替换为你数据中实际的唯一标识字段
          renderItem={({ item }) => <WorkoutCard workout={item} />} // 传递数据给卡片组件
          contentContainerStyle={styles.cardsContainer}
          onEndReached={loadMore}
          onEndReachedThreshold={0.1} // 距离底部10%时触发加载
          ListFooterComponent={renderFooter}
        />
      )}
    </View>
  )
}

export default Searchworkouts

关键说明

  • 分页参数:ExerciseDB API要求同时传递limit(每页数量)和offset(跳过的数据条数),仅传limit会返回全部数据。
  • 数据追加:加载更多时将新数据合并到现有数组,而非直接替换,实现滚动加载的连续列表。
  • 滚动触发:通过FlatList的onEndReached属性,在用户滚动到列表底部附近时自动触发加载更多逻辑。
  • 边界处理:当返回数据量小于设定的limit时,标记为无更多数据,避免无效请求;区分初始加载和加载更多状态,优化用户体验。

内容的提问来源于stack exchange,提问作者0x1dsawdwae

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 21:12:17