Flatlist onEndReached无限循环

时间:2018-05-16 19:48:38

标签: reactjs react-native react-native-android react-native-flatlist react-native-listview

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

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

on componentDidMount我手动调用函数_fetchData,将数据加载到this.state.data

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

一旦平面列表到达终点,即不再从服务器返回数据,它会进入无限循环,因为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>

    );
}

2 个答案:

答案 0 :(得分:0)

您正在使用加载数据时正在呈现的组件,对吧?所以你的公寓名单需要重新报名。你应该确保只要你多次达到你的目的,你只需要召唤一次获取方法。

答案 1 :(得分:0)

这是我的解决方案,可以更改以适合其他人的需求: 基本上,重要部分是onEndReached={this.state.moreData && 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);
    }
};