Flatlist onEndReached 无限循环

Posted

技术标签:

【中文标题】Flatlist onEndReached 无限循环【英文标题】:Flatlist onEndReached endless loop 【发布时间】:2018-10-26 23:29:54 【问题描述】:

我正在使用state 来存储以下数据。

state = 
    refresh: true,
    isFetching: true,
    showLoadingBottom: false,
    data: []
;

componentDidMount 上,我手动调用了一个函数_fetchData,它将数据加载到this.state.data

当平面列表滚动到末尾时,它会触发 _fetchData 两次,最终返回相同的数据两次(这是另一个问题,为什么它会触发两次?)。

一旦 flatlist 到达末尾,即不再从服务器返回数据,它就会进入无限循环,因为 onEndReached 会不断地反复触发,即使服务器没有返回新数据并且 @987654328 @ 保持不变。

这是我的render 代码

render() 

    return (

        <View
            style=
                flex: 1
            >

            <FlatList

                refreshControl=
                    <RefreshControl
                        refreshing=this.state.refresh
                        onRefresh=() => 
                            this.setState(
                                refresh: true
                            , this._fetchData);
                        
                        title="Pull To Refresh"
                        tintColor=darkGrey
                        titleColor=darkGrey/>
                

                onEndReachedThreshold=0.5
                onEndReached=() => 
                    this.setState(
                        showLoadingBottom: true
                    , () => 
                        this._fetchData();
                    );

                

                showsVerticalScrollIndicator=false

                data=this.state.data

                ListFooterComponent=() => 
                    return (
                        this.state.showLoadingBottom &&
                        <View style=padding: 10>
                            <ActivityIndicator size="small" color=colorAccent/>
                        </View>
                    );
                

                renderItem=this._renderItem

                keyExtractor=(item) => item.id.toString()

                removeClippedSubviews=true

            />

        </View>

    );

【问题讨论】:

你找到解决办法了吗? 【参考方案1】:

这是我的解决方案,可能会根据其他人的需要进行更改: 基本上重要的部分是onEndReached=this.state.moreData &amp;&amp; this.retrieveMore。因此,您可以在 onEndReached 函数中测试是否有更多数据(在我的情况下,如果我们只返回 1 个对象,我知道它已完成)然后将状态 this.state.moreData 设置为 false。

<SafeAreaView style=styles.container>
    <FlatList
        data=Object.values(this.state.documentData)
        // Render Items
        renderItem=( item ) => (
            <ItemSelector
                item=item
                onPress=() => this.selectItem(item)
            />
        )
        // On End Reached (Takes in a function)
        onEndReached=this.state.moreData && this.retrieveMore
        // How Close To The End Of List Until Next Data Request Is Made
        onEndReachedThreshold=1
        ListEmptyComponent=
            <Text>No jobs to show</Text>
        
    />
</SafeAreaView>

retrieveMore = async () => 
    try 

        // Set State: Refreshing
        this._isMounted && this.setState( refreshing: true );

        fbDb.ref('job')
            .orderByKey()
            .startAt(this.state.lastVisible) //Start at the last item we found
            .limitToFirst(this.state.limit) //Limit queries returned per page
            .once('value', snapshot => 

                //check if we got a result
                if(snapshot.numChildren() > 1)

                    .....
                    this._isMounted && this.setState(
                        documentData: newstate,
                        lastVisible: lastVisible,
                        refreshing: false, //Hide loading icon
                    );
                 else 
                    this._isMounted && this.setState(
                        refreshing: false, //Hide loading icon
                        moreData: false
                    );
                
            );
    
    catch (error) 
        console.log(error);
    
;

【讨论】:

【参考方案2】:

您正在使用加载数据时正在呈现的组件,对吗?所以你的平面列表需要重新渲染。即使您多次达到目的,您也必须确保只调用一次 fetch 方法。

【讨论】:

你建议我怎么做?我可以在现有代码中添加什么来允许我这样做? 您已经知道您是否在状态下显示底部加载程序。因此,仅在未显示的情况下触发 fetchdata 就足够了。如果 showLoadingBottom 为真,请尽早退出 onEndReached 并执行您当前正在执行的操作。

以上是关于Flatlist onEndReached 无限循环的主要内容,如果未能解决你的问题,请参考以下文章

Tips——Flatlist的onEndReached多次触发问题解决

React-Native 使用 Flatlist 滚动到顶部

React-Native:在ios中传递空数组时,Flatlist和Sectionlist引发异常

当我们到达列表底部时,React Native FlatList 加载更多

RN FlatList使用详解及源码解析

React Native FlatList 添加新项目时跳到顶部