Search code examples
javascriptreactjsreact-nativereduxreact-native-flatlist

onEndReached on flatlist invoked endless [React Native]


I'm trying to develop my first app with ReactNative with Expo. But I have a problem with FlatList, the components make infinite call but I'm not at the end of the view. And second problem, maybe related, I've multiple screen, and when I'm on a other screen, the infinite api call doesnt stop..

An idea ?

the code :

import * as React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import * as WebBrowser from 'expo-web-browser';
import { RectButton, ScrollView, FlatList } from 'react-native-gesture-handler';
import UserRankingList from '../components/UserRankingList';

export default class RankingsScreen extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      loading: true,
      users: []
    };

    console.log("constructor")
  }

  componentDidMount() {
    console.log('componentDidMount')
    // Toggle the state every second
    this.getUsers(0)
  }

  getUsers(page) {
    console.log('getUsers')
    console.log('make request with page ' + page)
    return fetch('https://myapi/users/' + page + '/10/', {
      method: 'GET',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
        'X-Instance': 'myinstance'
      }
    })
      .then(response => response.json())
      .then(responseJson => {
        let users = this.state.users
        this.setState({
          loading: false,
          users: [...this.state.users, ...responseJson]
         })
      })
      .catch(error => {
        console.error(error);
      });
  }

  loadMoreUser() {
    console.log('loadMoreUser')
    if (this.state.users.length >= 10 && (this.state.users.length % 10) === 0 && !this.state.loading) {
      let page = this.state.users.length / 10
      this.getUsers(page)
    }
  }

  render() {
    console.log('render')
  
    return (
      <View>
        <FlatList
          contentContainerStyle={{flexGrow:1}}
          data={this.state.users}
          refreshing={this.state.loading}
          keyExtractor={(item) => item.userid}
          onEndReached={this.loadMoreUser()}
          onEndReachedThreshold={0.1}
          renderItem={({ item }) => (
            <UserRankingList user={item}/>
          )}
          />
      </View>
    );
  }
}



function getRanking() {
  return fetch('https://myapi/users/0/10/', {
    method: 'GET',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
      'X-Instance': 'myinstance'
    }
  })
    .then(response => response.json())
    .then(responseJson => {
      console.log(responseJson)
      return responseJson;
    })
    .catch(error => {
      console.error(error);
    });
}

And the output :

constructor

render

loadMoreUser

componentDidMount

getUsers

make request with page 0

render

loadMoreUser

getUsers

make request with page 1

render

loadMoreUser

getUsers

make request with page 2

render

loadMoreUser

getUsers

make request with page 3

render

loadMoreUser

getUsers

make request with page 4


Solution

  • You should use arrow function.

    Instead of :

    onEndReached={this.loadMoreUser()}
    

    Use this :

    onEndReached={ () => { this.loadMoreUser() } }
    

    As you, i have to read a little more the documentation.