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

React Native列表仅渲染20项求助:150条数据无法全部加载

问题解决:仅渲染20条数据的原因及修复方案

核心原因:Yelp API默认返回限制

Yelp的Business Search API默认只返回20条数据,你当前的请求没有添加分页参数,所以实际只拿到了第一页的20条数据,并非渲染逻辑问题。要获取更多数据,需要通过offset参数实现分页请求。

修复步骤

1. 新增分页相关状态

在HomeScreen中添加分页所需的状态变量:

const [serviceData, setServiceData] = useState(localServices)
const [city, setCity] = useState("San Francisco")
const [activeTab, setActiveTab] = useState("Delivery");
const [loading, setLoading] = useState(false)
// 新增分页状态
const [offset, setOffset] = useState(0)
const [hasMore, setHasMore] = useState(true) // 标记是否还有更多数据可加载

2. 修改API请求函数,支持分页并合并数据

修改getServicesFromYelp函数,添加offset参数,并且将新请求到的数据合并到现有数据中(而非直接替换):

const getServicesFromYelp = (isLoadMore = false) => {
    // 给请求URL添加offset和limit参数
    const yelpUrl = `https://api.yelp.com/v3/businesses/search?term=Home+Services&location=${city}&offset=${offset}&limit=20`;

    const apiOptions = {
        headers: {
            Authorization: `Bearer ${YELP_API_KEY}`,
        },
    };
    setLoading(true)
    return fetch(yelpUrl, apiOptions)
        .then((res) => res.json())
        .then((json) => {
                setLoading(false)
                if(json.error) return Alert.alert('Sorry', json.error.description);
                
                const newData = json?.businesses?.filter(business => business) || []
                // 加载更多时合并数据,首次请求时替换数据
                if (isLoadMore) {
                    setServiceData(prev => [...prev, ...newData])
                    // 返回数据不足20条,说明没有更多数据了
                    setHasMore(newData.length === 20)
                } else {
                    setServiceData(newData)
                    setHasMore(newData.length === 20)
                }
            }
        );
};

3. 切换城市/标签时重置分页

当切换城市或标签时,需要重置分页起始位置和数据:

useEffect(() => {
    setOffset(0) // 重置分页起始点
    getServicesFromYelp();
}, [city, activeTab]);

4. 替换ScrollView为FlatList,实现滚动加载更多

原代码用ScrollView包裹所有内容会导致性能问题,且无法触发滚动加载逻辑。将主容器换成FlatList,把头部元素作为ListHeaderComponent,并添加滚动触底加载更多的逻辑:

修改HomeScreen的return部分:

return (
    <Screen style={tailwind`bg-white flex-1`}>
        <FlatList
            style={tailwind`flex-1`}
            showsVerticalScrollIndicator={false}
            data={serviceData}
            keyExtractor={(item) => item.id} // 改用唯一id作为key,避免index导致的渲染异常
            ListHeaderComponent={() => (
                <>
                    <HeaderTabs activeTab={activeTab} setActiveTab={setActiveTab} />
                    <SearchBar setCity={setCity} city={city} />
                    <Categories />
                    {loading && <ActivityIndicator size="large" color={colors.primary} style={tailwind`mt-2 mb-6`} />}
                </>
            )}
            renderItem={({item}) => <ServiceItemCard item={item} />}
            // 滚动到距离底部10%位置时触发加载更多
            onEndReached={() => {
                if (hasMore && !loading) {
                    setOffset(prev => prev + 20)
                    getServicesFromYelp(true)
                }
            }}
            onEndReachedThreshold={0.1}
            // 底部加载状态指示器
            ListFooterComponent={() => {
                if (hasMore && loading) {
                    return <ActivityIndicator size="small" color={colors.primary} style={tailwind`py-4`} />
                }
                return null
            }}
        />
    </Screen>
);

5. 移除冗余的ServiceItem组件

现在直接通过FlatList的renderItem渲染ServiceItemCard,可以删除ServiceItem组件简化结构。

额外优化点

  • 图片加载优化:给Image组件添加默认占位图,避免图片加载失败时显示空白:
<Image
    source={{ uri: item.image_url || 'https://via.placeholder.com/300x200' }}
    style={tailwind`w-full h-48 rounded-lg`}
    resizeMode="cover"
/>

验证效果

修改完成后,滚动到列表底部时会自动请求下一页数据,直到没有更多内容为止,此时就能看到超过20条的卡片了。

内容的提问来源于stack exchange,提问作者Lance Nieva

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 06:45:32