Flatlist onEndReached 无限循环

Jud*_*des 7 reactjs react-native react-native-listview react-native-android react-native-flatlist

state用来存储以下数据。

state = {
    refresh: true,
    isFetching: true,
    showLoadingBottom: false,
    data: []
};
Run Code Online (Sandbox Code Playgroud)

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

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

一旦 flatlist 到达末尾,即没有更多数据从服务器返回,它就会进入一个无限循环,因为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>

    );
}
Run Code Online (Sandbox Code Playgroud)

asi*_*swt 5

我有一个类似的问题。就我而言,这是因为ListFooterComponent.

ListFooterComponent如果您使用此模式或等效模式渲染

onEndReachedThreshold={x} // for any x >= 0
ListFooterComponent={() => {
  if (isDataFetching) {
    return <SomeComponentWithSomeHeight />
  } else {
    return undefined;
  }
}}
Run Code Online (Sandbox Code Playgroud)

onEndReached当用户向下滚动列表末尾(或者您的内容不长于列表的可见区域)时,它将无限触发。

正是因为 的存在和不存在会<SomeComponentWithSomeHeight />影响内容的高度,从而触发endReached重新计算。

FlatList onEndReached 无限循环

以下是我能想到的可能的解决方案。

  1. 使用onEndReachedThreshold始终“高于”高度的负数ListFooterComponent。但我不喜欢这个解决方案,因为很难知道“更高”(它是相对于 FlatList 的可见区域)。负面影响onEndReachedThreshold可能会在 Android 上引起一些问题。

  2. 在外部实现您自己的加载覆盖,FlatList以便加载组件不会影响内容高度。

  3. 设置为opacity = 0隐藏ListFooterComponent而不是返回undefined,以便它始终存在并且当它变得可见时内容高度不会改变。

ListFooterComponent={() => {
  return (
    <View style={{ opacity: isDataFetching ? 1 : 0 }}>
      <SomeComponentWithSomeHeight />
    </View>
  );
}}
Run Code Online (Sandbox Code Playgroud)


Val*_*ery -1

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