Skip to content

[FlatList] onEndReached triggered 2 times #14015

Closed
@fengshanjian

Description

@fengshanjian

<FlatList
ref={(flatList)=>this._flatList = flatList}
ListHeaderComponent={this._header}
ListFooterComponent={this._footer}
ItemSeparatorComponent={this._separator}
renderItem={this._renderItem}
getItemLayout={(data,index)=>({length: ITEM_HEIGHT, offset: (ITEM_HEIGHT+2) * index, index})}
onEndReachedThreshold={0.5}
onEndReached={(info)=>{
console.log(JSON.stringify(info));
}}
data={data}
/>

When the scroll speed is fast enough,onEndReached triggered 2 times or more times

Is there any solution?

Activity

parkerproject

parkerproject commented on May 17, 2017

@parkerproject

mine doesn't even trigger.

fengshanjian

fengshanjian commented on May 18, 2017

@fengshanjian
Author

@parkerproject
My paltform is ios 10.3,mac osx 10.12.5

benderlidze

benderlidze commented on May 18, 2017

@benderlidze

@fengshanjian
Yep, got the same - fires 2 times. But if you are using redux or even state - you can use something like this

onEndReached={(info)=>{
if (this.state.loading===false){
console.log(JSON.stringify(info));
}
}}
JonoH

JonoH commented on May 31, 2017

@JonoH

Same issue my side. Seems to be a bug in the ScrollView bouncing feature on iOS (when you over scroll on iOS the ScrollView scrolls past the content and bounces back to the end of the content by default).

Setting bounces={false} solved onEndReached being called twice for me. Still not an ideal solution though as you lose that nice smooth/fluid feel in the UX.

changed the title [-]FlatList onEndReached triggered 2 times[/-] [+][FlatList] onEndReached triggered 2 times[/+] on Jun 2, 2017
hramos

hramos commented on Jun 2, 2017

@hramos
Contributor

Hey, thanks for reporting this issue!

It looks like your description is missing some necessary information. Can you please add all the details specified in the template? This is necessary for people to be able to understand and reproduce the issue being reported.

grin

grin commented on Jun 23, 2017

@grin

I'm definitely seeing the second onEndReached call triggered by the bouncing effect on iOS. Adding bounces={false} to the FlatList fixed it for me. I think ideally, RN should not call onEndReached while the list is in the "bouncing" state. Not sure how doable is this though.

grin

grin commented on Jun 23, 2017

@grin

OK, here is my solution for how to avoid the second onEndReached call with the bouncing effect enabled on iOS:

  1. Add onMomentumScrollBegin prop to your FlatList declaration.
        <FlatList
          data={this.props.data}
          onEndReached={...}
          onEndReachedThreshold={0.5}
          ...
          onMomentumScrollBegin={() => { this.onEndReachedCalledDuringMomentum = false; }}
        />
  1. Modify your onEndReached callback to trigger data fetching only once per momentum.
  onEndReached = () => {
    if (!this.onEndReachedCalledDuringMomentum) {
      this.props.fetchData();
      this.onEndReachedCalledDuringMomentum = true;
    }
  };

Tested with RN 0.44.0.

gonglong

gonglong commented on Jul 22, 2017

@gonglong

hi @grin can you pls refer me some document about the function onMomentumScrollBegin? i cannot find any on http://facebook.github.io/react-native/releases/0.46/docs/flatlist.html

vomchik

vomchik commented on Jul 31, 2017

@vomchik

FlatList is just wrapper of the ScrollView

hramos

hramos commented on Jul 31, 2017

@hramos
Contributor

Hey, thanks for reporting this issue!

It looks like your description is missing some necessary information, or the list of reproduction steps is not complete. Can you please add all the details specified in the template? This is necessary for people to be able to understand and reproduce the issue being reported.

I am going to close this, but feel free to open a new issue with the additional information provided. Thanks!

8 remaining items

harish-aka-shivi

harish-aka-shivi commented on Dec 21, 2017

@harish-aka-shivi

Was also happening with me, try keeping a flag to stop making request.

if (!this.state.loading) {
    this.setState({loading:true});
    this.setState(state => ({ page: state.page+1}), this.makeNetworkRequest());
}

Then I set the state to loading false after completing of request

AyubaMakoa

AyubaMakoa commented on Jan 30, 2018

@AyubaMakoa

`constructor(props){
super(props);
this.state = {
flatListReady:false
}
}

_scrolled(){
this.setState({flatListReady:true})
}

loadMore = () => {
if(!this.state.flatListReady){ return null}

//you can now load more data here from your backend

}

<FlatList
onScroll={this._scrolled.bind(this)}
style={{width:'100%',flexGrow:1}}
ListHeaderComponent={this.headerComponent}
data={this.props.data}
renderItem={this.renderItem}
keyExtractor={(item,index) => index }
onEndReached={(x) => {this.loadMore()}}
onEndReachedThreshold={0.5}

           />

`

anil1712

anil1712 commented on Feb 2, 2018

@anil1712

onEndReached is not working as expected. It's not triggering continuously when we reached the end.
FYI: I am using the native-base components.

gougoushan

gougoushan commented on Feb 11, 2018

@gougoushan

using setTimeout for setState, eg.
setTimeout(() => this.setState({ arr: [ ...newArr ] }), 3000);

anil1712

anil1712 commented on Feb 12, 2018

@anil1712

@gougoushan Not working for me

nsyujian

nsyujian commented on Mar 16, 2018

@nsyujian

don't use onEndReached
react-native-refresh-list-view

  onScroll = ({nativeEvent}) => {
        let previousOffsetY = 0;
        if (this.nativeEvent) {
            previousOffsetY = this.nativeEvent.contentOffset.y;
        }
        const offsetY = nativeEvent.contentOffset.y;

        /**
         * 判断是否为用户拖拽
         */
        if (this.isResponder) {
            /**
             * 判断为上拉并且滚动到底部
             */
            if ((offsetY - previousOffsetY) > 0 && offsetY >= (nativeEvent.contentSize.height + nativeEvent.contentInset.bottom - nativeEvent.layoutMeasurement
                    .height)) {
                if (this.shouldStartFooterRefreshing()) {
                    this.props.onFooterRefresh && this.props.onFooterRefresh(RefreshState.FooterRefreshing);
                }
            }
        }

        this.nativeEvent = nativeEvent;
    }

mtx62

mtx62 commented on Apr 9, 2018

@mtx62

@GaoYuJian You are a hero!!

chunghalu

chunghalu commented on May 16, 2018

@chunghalu

This is my solution:

<FlatList
  ...
  refreshing={this.state.refreshing}
  onRefresh={this._onRefresh}
  onEndReached={this._onEndReached}
  onEndReachedThreshold={0.2}
  onScrollBeginDrag={() => {
    console.log('onScrollBeginDrag');
    this.canAction = true;
  }}
  onScrollEndDrag={() => {
    console.log('onScrollEndDrag');
    this.canAction = false;
  }}
  onMomentumScrollBegin={() => {
    console.log('onMomentumScrollBegin');
    this.canAction = true;
  }}
  onMomentumScrollEnd={() => {
    console.log('onMomentumScrollEnd');
    this.canAction = false;
  }}
/>
_onRefresh = () => {
  console.log('_onRefresh');
  if(!this.canAction) return;
  ...
  };

_onEndReached = () => {
  console.log('_onEndReached');
  if(!this.canAction) return;
  ...
};
rizwanahmed19

rizwanahmed19 commented on Jul 4, 2018

@rizwanahmed19

For some reasons my onMomentumScrollBegin is not being fired. Is this happening to anybody else?

pisacode

pisacode commented on Jul 5, 2018

@pisacode

I have solved it with using debounce from lodash

first import debounce from 'lodash.debounce'

and then just add this to your constructor

this._onEndReached = debounce(this._onEndReached, 500);

bnbon

bnbon commented on Jul 23, 2018

@bnbon

Is this going to be fixed in the next release or is the hack necessary?

locked as resolved and limited conversation to collaborators on Jul 31, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @grin@zachrnolan@hramos@parkerproject@vomchik

        Issue actions

          [FlatList] onEndReached triggered 2 times · Issue #14015 · facebook/react-native