FlatList在渲染时调用`onEndReached`

hel*_*eer 15 react-native

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

最近我为我的FlatListView 添加了分页,所以当用户滚动到底部时,onEndReached在某个点(onEndReachedThreshold从底部开始的值长度)中调用,它将获取下一个categories并连接类别props.

但我的问题是在调用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>
)
Run Code Online (Sandbox Code Playgroud)

更新this.props.categories在这里获取数据

  componentWillMount() {
    if(this.props.token) {
      this.props.loadCategoryAll(this.props.token);
    }
  }
Run Code Online (Sandbox Code Playgroud)

Ila*_*rio 33

尝试实施onMomentumScrollBeginFlatList:

constructor(props) {
    super(props);
    this.onEndReachedCalledDuringMomentum = true;
}
Run Code Online (Sandbox Code Playgroud)

...

<FlatList
    ...
    onEndReached={this.onEndReached.bind(this)}
    onEndReachedThreshold={0.5}
    onMomentumScrollBegin={() => { this.onEndReachedCalledDuringMomentum = false; }}
/>
Run Code Online (Sandbox Code Playgroud)

并修改你的 onEndReached

onEndReached = ({ distanceFromEnd }) => {
    if(!this.onEndReachedCalledDuringMomentum){
        this.fetchData();
        this.onEndReachedCalledDuringMomentum = true;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 抱歉,没有。它只呈现第一页 (3认同)
  • 仅当您**滚动滑行** _(即拖动并放开)_时,才可以使用`onMomentumScrollBegin` ......如果您缓慢拖至结尾**(不放开),则不会注册。 (3认同)
  • 有趣的。onEndReached 只触发一次 (2认同)

lou*_*ity 24

我有它的工作

<Flatlist
    ...
    onEndReached={({ distanceFromEnd }) => {
        if (distanceFromEnd < 0) return;
        ...
    }
    ...
/>
Run Code Online (Sandbox Code Playgroud)


Nag*_*aba 9

首先检查FlatList是否在ScrollViewContent本机基础内。然后将其带到它之外实际上,您不需要使用Contentor ScrollView,因为FlatList同时具有ListFooterComponentListHeaderComponent

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

  • 是的,我的 FlatList 在滚动视图内,删除它后问题就消失了 (2认同)

Lea*_*roG 9

经过数小时的尝试不同的方法后,我通过使用固定高度和 flex:1 的 View 包裹 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>
    )
}
Run Code Online (Sandbox Code Playgroud)

我的 onEndReached() 函数只是调用 API 并更新我的数据。它不会对到底部的距离或阈值进行任何计算


Vic*_*ina 9

大多数时候,此错误是由于 onEndReachedThreashold 的错误使用而引起的,这也取决于您正在渲染的项目数量(更多项目,更多滚动大小)。

尝试遵循这个逻辑:

如果 10 个项目覆盖您的屏幕,并且您在每个滚动条上渲染 20 个项目,则将 onEndReachedThreashold 设置为 0.8。

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

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

只需使用 onEndReachedThreashold 值即可。


其他时候,此错误是由于嵌套滚动视图而产生的。不要将 FlatList 放在 ScrollView 中。相反,请使用 FlatList header 和 footer 属性。


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