Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React native List View onEndReached calling multiple times

I am facing some trouble using the List View onEndReached component in react native.

Render code:

@autobind
  _fetchMoreHistory(){

    console.log("Fetch more history called");

  }

<View style={[styles.Ctr]}>
   <ListView dataSource={this.state.txHistorySource}
         renderRow={ this._renderRow }
         onEndReached ={ this._fetchMoreHistory }
         onEndReachedThreshold  = {10}/>
</View>

The moment I open the screen _fetchMoreHistory is called twice and works normally after that onEndReached reached. Can someone help debug this ?

like image 515
firebolt_ash Avatar asked Dec 23 '16 07:12

firebolt_ash


4 Answers

I faced the same issue and searched a lot but didn't find any answers, so I used a condition to check if the first request got the data I fire onendreashed again else I don't

Example // onEndReached If(condition) { Make the call }

like image 182
Ahmed Ali Avatar answered Nov 11 '22 17:11

Ahmed Ali


So my solution is simple. Don't use onEndReached at all. Use onScroll and detect the end of the scroll.

isCloseToBottom = ({ layoutMeasurement, contentOffset, contentSize }) => { const paddingToBottom = 20; // how far from the bottom return layoutMeasurement.height + contentOffset.y >= contentSize.height - paddingToBottom; };

and the FlatList component

 <FlatList      
      data={data}        
       onScroll={({ nativeEvent }) => {
          if (this.isCloseToBottom(nativeEvent)) {
            // Dont forget to debounce or throttle this function.
            this.handleOnEndReached();
          }
       }}
  />
like image 4
Nicholas Avatar answered Nov 11 '22 19:11

Nicholas


I had the same issue. But I figured out that I had the ScrollView that wraps my FlatList. When I removed it all started working properly.

It's a pity that NOTHING WAS SAID ABOUT THAT IN THE OFFICIAL DOCS

like image 4
Pavel Poberezhnyi Avatar answered Nov 11 '22 18:11

Pavel Poberezhnyi


You can try my solution

  1. You should configure limit > 10. Example limit = 15
  2. Add onMomentumScrollBegin prop to your ListView declaration.

    <ListView
      data={this.props.data}
      onEndReached={...}
      onEndReachedThreshold={0.5}
      ...
      onMomentumScrollBegin={() => { this.onEndReachedCalledDuringMomentum = false; }}
    />
    
  3. Modify your onEndReached callback to trigger data fetching only once per momentum.

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

like image 2
tam nguyen Avatar answered Nov 11 '22 19:11

tam nguyen