FlatList在呈现时调用`onEndReached`

时间:2017-12-20 16:06:05

标签: react-native

这是我的简单category list page的render()函数。

最近我为FlatList视图添加了分页,因此当用户滚动到底部时,onEndReached会在某个点(onEndReachedThreshold从底部开始的值长度)中被调用,并且它将获取下一个categories并连接类别道具。

但我的问题是在调用render()时调用onEndReached 换句话说,FlatList的onEndReached在它到达底部之前被触发。

我是否为onEndReachedThreshold?提供了错误的价值你觉得有什么问题吗?

return (
  <View style={{ flex:1 }}>
    <FlatList
      data={this.props.categories}
      renderItem={this._renderItem}
      keyExtractor={this._keyExtractor}
      numColumns={2}
      style={{flex: 1, flexDirection: 'row'}}
      contentContainerStyle={{justifyContent: 'center'}}
      refreshControl={
        <RefreshControl
          refreshing = {this.state.refreshing}
          onRefresh = {()=>this._onRefresh()}
        />
      }
      // curent value for debug is 0.5
      onEndReachedThreshold={0.5} // Tried 0, 0.01, 0.1, 0.7, 50, 100, 700

      onEndReached = {({distanceFromEnd})=>{ // problem
        console.log(distanceFromEnd) // 607, 878 
        console.log('reached'); // once, and if I scroll about 14% of the screen, 
                             //it prints reached AGAIN. 
        this._onEndReachedThreshold()
      }}
    />
  </View>
)

更新我在此处获取this.props.categories数据

  componentWillMount() {
    if(this.props.token) {
      this.props.loadCategoryAll(this.props.token);
    }
  }

12 个答案:

答案 0 :(得分:18)

尝试在onMomentumScrollBegin上实施FlatList

constructor(props) {
    super(props);
    this.onEndReachedCalledDuringMomentum = true;
}

...

<FlatList
    ...
    onEndReached={this.onEndReached.bind(this)}
    onEndReachedThreshold={0.5}
    onMomentumScrollBegin={() => { this.onEndReachedCalledDuringMomentum = false; }}
/>

并修改您的onEndReached

onEndReached = ({ distanceFromEnd }) => {
    if(!this.onEndReachedCalledDuringMomentum){
        this.fetchData();
        this.onEndReachedCalledDuringMomentum = true;
    }
}

答案 1 :(得分:18)

我已经与它合作

<Flatlist
    ...
    onEndReached={({ distanceFromEnd }) => {
        if (distanceFromEnd < 0) return;
        ...
    }
    ...
/>

答案 2 :(得分:10)

首先检查FlatList是否在本机库的ScrollViewContent内部。然后把它带到外面 实际上,您不需要使用ContentScrollView,因为FlatList同时具有ListFooterComponentListHeaderComponent

尽管不建议这样做,但是如果您确实需要在ScrollView中使用Flatlist,请查看以下答案:https://stackoverflow.com/a/57603742/6170191

答案 3 :(得分:1)

删除FlatList中的每个 Scrollable 视图

答案 4 :(得分:1)

经过数小时的尝试,我通过用固定高度和flex:1的视图包装Flatlist使其工作。 有了此设置,只有在滚动底部时,我才能调用一次onEndReached。这是我的代码示例:

render() {
    const {height} = Dimensions.get('window');
    return (    
        <View style={{flex:1, height:height}}>
            <FlatList
                data={this.props.trips_uniques}
                refreshing={this.props.tripsLoading}
                onRefresh={()=> this.props.getTripsWatcher()}
                onEndReached={()=>this.props.getMoreTripsWatcher()}
                onEndReachedThreshold={0.5}
                renderItem={({item}) => (
                <View style={Style.card}> 
                    ...
                    ...
                </View>
                )}
                keyExtractor={item => item.trip_id}
            />
        </View>
    )
}

我的onEndReached()函数仅调用API并更新我的数据。它不做任何关于到底部的距离或阈值的计算

答案 5 :(得分:0)

也许您可以在进行异步调用之前增加页面来绕过FlatList错误,然后您将在每个onEndReached节点上获取数据,而不会出现重复键的错误

答案 6 :(得分:0)

我已经使用lodash的反跳功能解决了这个问题。首先,我从“ lodash.debounce”导入反跳。然后我使用去抖动功能以500毫秒的间隔加载更多功能

<Flatlist onEndReached = {debounce(this._onLoadMore, 500)} />

答案 7 :(得分:0)

(自19年11月起)

1)将平面列表作为单个视图中的唯一组件
2)从{{flex: 1, height: Dimensions.get('window')}}

等维度设置该单一视图的样式

答案 8 :(得分:0)

如果要显示3或4条记录,并且想在到达末尾时加载下一个数据。将onEndReachedThreshold设置为0或0.1。

答案 9 :(得分:0)

如果FlatList在另一个FlatList或ScrollView上,则在呈现组件以解决该问题的情况下,onEndReached调用不会立即将FlatList与另一个包裹在一起。

答案 10 :(得分:0)

在大多数情况下,此错误是由于onEndReachedThreashold的使用不正确引起的,而onEndReachedThreashold的使用还取决于要渲染的项目数(更多项目,更多滚动大小)。

尝试遵循以下逻辑:

如果10个项目覆盖了屏幕,并且每次滚动显示20个项目,则将onEndReachedThreashold设置为0.8。

如果2或3个项目覆盖了您的屏幕,并且您要在每个滚动上渲染10个项目,则将onEndReachedThreashold设置为0.5。

另外,使用initialNumToRender = numItems。由于某些原因,使用此FlatList属性有助于减少多次onEndReached调用的机会。

只需使用onEndReachedThreashold值即可。


有时,由于嵌套滚动视图而产生此错误。不要将FlatList放在ScrollView中。相反,请使用FlatList的页眉和页脚道具。


对于这两种解决方案,我建议将FlatList样式和contentContainerStyle设置为{flexGrow:1}。

答案 11 :(得分:0)

我在 <FlatList>(来自 react-native-elements)中有一个 <Overlay>(来自 react-native)。我遇到了 onEndReached 被执行的问题在用户执行任何操作之前第一次呈现。

问题已通过使用 <Modal>(来自 react-native)而不是 <Overlay> 解决。