Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FlatList onEndReached being called multiple times [duplicate]

I'm making a react native project where user can search images using Flickr API, Everything else is working fine but the problem i'm having while implementing pagination. I have used FlatList's onEndReached to detect when user has scrolled to the end on the list, but the problem is onEndReached is being called multiple times(including one during the first render). I have even disabled bounce as said here but it's still being called more than once

 export default class BrowserHome extends React.Component {   constructor(props) {     super(props);     this.state = {       isLoading: false,       tagParam: "cat",       pageNum: -1,       data: [],       photosObj: ""     };   }    componentDidMount() {     this.setState({       isLoading: true     });     try {       this.makeRequest();     } catch {       console.log("error has occurred");     }   }    makeRequest = () => {     const { tagParam, pageNum } = this.state;     let url = `https://api.flickr.com/services/rest/?                 method=flickr.photos.search                &api_key=${apiKey}&format=json&tags=${tagParam}                &per_page=30&page=${pageNum + 1}&nojsoncallback=1`;     fetch(url, {       method: "GET"     })       .then(response => response.json())       .then(responseJSON => {         this.setState({           data: this.state.data.concat(responseJSON.photos.photo),           isLoading: false,           pageNum: responseJSON.photos.page         });       })       .catch(error => {         console.log(error);         this.setState({ isLoading: false });         throw error;       });   };    render() {     if (this.state.isLoading) {       return <ActivityIndicator animating={true} size="large" />;     }      return (       <View         style={{           flex: 1,           height: 200,           justifyContent: "flex-start",           width: screenSize.width,           backgroundColor: "black"         }}       >         <Text>This is browserhome</Text>         <FlatList           style={{             width: screenSize.width           }}           numColumns={3}           data={this.state.data}           keyExtractor={item => item.id}           bounces={false}           onEndReachedThreshold={1}           onEndReached={({ distanceFromEnd }) => {             this.loadMoreItem();             alert("end reached call");           }}           renderItem={({ item, index }) => (             <>               <ImageTile imageURL={this.createImageURL(item)} />             //  <Text style={{ color: "white" }}>              //   {index}              //   {console.log(index)}              // </Text>             </>           )}         />       </View>     );   }    createImageURL(item) {     let server = item.server,       id = item.id,       secret = item.secret;     let urlString = `https://farm${       item.farm     }.staticflickr.com/${server}/${id}_${secret}_s.jpg`;     return urlString;   }    loadMoreItem() {     this.makeRequest();   } } 
like image 635
Romit Kumar Avatar asked Nov 21 '18 09:11

Romit Kumar


Video Answer


2 Answers

This solution worked for me. Add onMomentumScrollBegin and modify onEndReached in FlatList Component.

<FlatList  style = { ...}  data = {data}  initialNumToRender = {10}  onEndReachedThreshold = {0.1}  onMomentumScrollBegin = {() => {this.onEndReachedCalledDuringMomentum = false;}}  onEndReached = {() => {      if (!this.onEndReachedCalledDuringMomentum) {        this.retrieveMore();    // LOAD MORE DATA        this.onEndReachedCalledDuringMomentum = true;      }    }  }  />
like image 182
Shehzad Osama Avatar answered Sep 30 '22 20:09

Shehzad Osama


You would be best using onEndReached to set a boolean true, and then using onMomentumScrollEnd based on that.

onEndReached={() => this.callOnScrollEnd = true} onMomentumScrollEnd={() => {   this.callOnScrollEnd && this.props.onEndReached()   this.callOnScrollEnd = false } 
like image 28
James Trickey Avatar answered Sep 30 '22 21:09

James Trickey