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(); } }
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; } } } />
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 }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With