繁体   English   中英

Flatlist onEndReached 无限循环

[英]Flatlist onEndReached endless loop

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

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

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

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

一旦 flatlist 到达末尾,即没有更多的数据从服务器返回,它就会进入一个无限循环,因为onEndReached不断地一遍onEndReached触发,即使没有从服务器返回新的数据并且this.state.data仍然是相同的。

这是我的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>

    );
}

这是我的解决方案,可以更改以适应其他人的需求:基本上重要的部分是onEndReached={this.state.moreData && this.retrieveMore} 所以你可以在你的onEndReached函数中测试天气是否有数据(在我的情况下,如果我们只返回 1 个对象,我知道它已经完成)然后将 state 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);
    }
};

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM