Emilios1995
Emilios1995

Reputation: 507

ListView's onEndReached not working when inside a View

Here is the thing. I want to render a listview that updates the data when onEndReached.

While the data is updated, I want to render a 'loading' text below the list (without removing the list). like this:

render() {
  var {isFetching} = this.props.query
  var loading
  if(isFetching){
    loading = this.renderLoading()
  }
  return (
      <ListView
        dataSource={this.dataSource}
        renderRow={this.renderItem}
        onEndReached={this.props.fetchNextPage}
        onEndReachedThreshold={10}
        style={styles.listView} />
      {loading}
  )
}
renderLoading () {
  return (
    <View style={styles.loading}>
      <ActivityIndicatorIOS
        size='large'/>
      <Text>
        Loading books...
      </Text>
    </View>
  )
}

But soon I realised that the render function has to return a single element. So I tried this:

return (
    <View>
      <ListView
        dataSource={this.dataSource}
        renderRow={this.renderItem}
        onEndReached={this.props.fetchNextPage}
        onEndReachedThreshold={10}
        style={styles.listView}/>
      {loading}
    </View>  
  )

But then the onEndReached fired again and again and again as soon as it was mounted. Even before I touched the screen.

How can I achieve the loading view, while keeping the 'infinite scroll' behavior?

Upvotes: 1

Views: 6884

Answers (4)

Suhail Jain
Suhail Jain

Reputation: 146

One of the possible reasons for your list to be rendering again and again could be the value of onEndReachedThreshold={10} here.

For values more than or equal 1, the method in onEndReached is going to be called as soon as render is called.

Set a value say 0.5 which would mean that onEndReached method is going to be invoked when half of the current list is scrolled.

Upvotes: 0

user5018827
user5018827

Reputation:

you can try to give ListView a height(eg:height:300)

Upvotes: 2

Alan
Alan

Reputation: 634

You don't need to render it as the listView footer. Try giving the wrapping view style: {flex: 1}:

return (
    <View style={{flex: 1}}>
      <ListView
        dataSource={this.dataSource}
        renderRow={this.renderItem}
        onEndReached={this.props.fetchNextPage}
        onEndReachedThreshold={10}
        style={styles.listView}/>
      {loading}
    </View>  
  )

Upvotes: 0

Emilios1995
Emilios1995

Reputation: 507

I finally used a workaround. I rendered the loading view as the footer of the listView.

Upvotes: 1

Related Questions