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

React Native BigList停止加载 未触发onEndReached问题

问题原因

你的代码存在4个核心逻辑漏洞,才会导致滚动几次后加载停止:

  • 闭包陷阱:getData函数内读取的pageNumber、loading、homeImages都是函数创建时的旧状态值,不是最新的实时值,滚动几次后状态值和实际值偏差越来越大,会出现加载锁判断错误、页码计算错误的问题
  • 加载锁死:原代码catch分支没有重置loading状态,只要出现一次请求报错,loading就会永久为true,后续触发getData时会直接跳过请求逻辑
  • 触发阈值缺失:BigList默认的onEndReached触发阈值极小,只有滚动到列表最底部边缘才会触发,快速滚动时很容易错过判定点,导致回调不执行
  • 状态更新竞态:原代码直接用setHomeImages([...homeImages, ...responseJson])的写法,多次快速触发加载时会出现新返回的数据覆盖之前已加载数据的问题
修复后代码
import React, { useEffect, useState } from 'react';
import { View, Text, Image, Dimensions } from 'react-native';
import BigList from 'react-native-big-list';


const HomeScreen = ({ navigation }) => {

    const BaseURL = "http://localhost:12646/"
    const windowWidth = Dimensions.get('window').width;
    const [homeImages, setHomeImages] = useState([]);
    const [pageNumber, setPageNumber] = useState(1);
    const [loading, setLoading] = useState(false);

    useEffect(() => {
        getData();
    }, []);

    const getData = () => {
        if (loading) return;

        setLoading(true);
        const url = `${BaseURL}api/images/GetHomepageImages?PageNumber=${pageNumber}&PageSize=3`;
        fetch(url)
            .then((response) => response.json())
            .then((responseJson) => {
                // 函数式更新状态,规避闭包旧值问题
                setPageNumber(prev => prev + 1);
                setHomeImages(prev => [...prev, ...responseJson]);
                setLoading(false);
            })
            .catch((error) => {
                console.error(error);
                // 必须重置loading,否则请求失败后锁死
                setLoading(false);
            });
    }

    const renderItem = ({ item, index }) => {
        return (
            <View style={{ height: windowWidth }}>
                <Image
                    style={{ width: windowWidth, height: windowWidth }}
                    source={{ uri: `${BaseURL}images/${item.basePath}/${item.imageSquare}` }}
                />
            </View>
        );
    }

    const keyExtractor = (item, index) => item.id?.toString() || index.toString();

    return (
        <View style={{flex: 1}}>
            {
                homeImages.length > 0 ?
                    <BigList
                        data={homeImages}
                        onEndReached={getData}
                        onEndReachedThreshold={0.5} // 距离底部半个列表高度时提前触发加载
                        itemHeight={windowWidth}
                        renderItem={renderItem}
                        keyExtractor={keyExtractor}
                    />
                    : <Text>Loading</Text>
            }
        </View>
    )
};

export default HomeScreen;
关键修改说明
  • 所有依赖之前状态的更新操作都改用函数式写法,彻底解决闭包旧值导致的逻辑错误
  • 补全请求异常分支的loading重置逻辑,避免加载状态永久锁死
  • 新增onEndReachedThreshold={0.5}配置,将加载触发时机提前,避免快速滚动错过回调判定
  • 修正了原来setOffset的错误命名,统一为setPageNumber和状态名语义对齐
  • 新增keyExtractor属性,保证列表内部渲染计算的稳定性,减少列表高度判定偏差
  • 空状态判断从homeImages != null改为homeImages.length > 0,逻辑更准确,避免初始空数组时一直显示Loading

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 06:06:22