最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React native List View onEndReached calling multiple times - Stack Overflow

programmeradmin0浏览0评论

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 ?

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 ?

Share Improve this question edited Dec 23, 2016 at 7:31 firebolt_ash asked Dec 23, 2016 at 7:29 firebolt_ashfirebolt_ash 1,3244 gold badges13 silver badges21 bronze badges 2
  • How many rows are you fetching? onEndReached is executed at the end of the rendering of the rows, so you set the limit to 10, I think you have just more thant 10 rows. It's possible? – Mario Santini Commented Dec 23, 2016 at 7:36
  • Does this answer your question? FlatList calls `onEndReached` when it's rendered – luke77 Commented Oct 30, 2020 at 12:12
Add a comment  | 

6 Answers 6

Reset to default 6

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

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 }

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();
          }
       }}
  />

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; } };

I've solved this problem by creating a state variable that tells me is the service is loading or not.

class Component1 extends Component {
public constructor(props) {
    super(props);

    this.state = {
        isLoading: false,
        listOfItems: []
    };
}

public componentDidMount() {
    this.loadData();
}

public render(){
    return (
        <FlatList
            data={this.state.listOfItems}
            renderItem={this.renderItem}
            onEndReachedThreshold={0.1}
            onEndReached={this.loadData}
        />
    );
}

private loadData = () => {
    if (this.state.isLoading === true) {
        /// Avoid make another request is there's happening a request right now
        return;
    }

    this.setState({isLoading: true});

    this.fetchData()
        .then(() => {
        /// Handle success response
            this.setState({isLoading: false});
        })
        .catch(() => {
              this.setState({isLoading: false});
        });
}

}

You can write the code for fetching data in onMomentumScrollEnd rather than onEndReached, like this:

onMomentumScrollEnd={() => this.props.onEndReached()}

It might not be written as the available prop in the react native documentation, but if you will see the source code for FlatList, it uses Virtualized List which in return has the mentioned prop available.

发布评论

评论列表(0)

  1. 暂无评论