FlatList вызывает 'onEndReached', когда он рендерится

Вот функция render() для моей простой category list page.

Недавно я добавил разбивку на страницы для своего FlatList View, поэтому, когда пользователь прокручивается в нижнюю часть, onEndReached вызывается в определенной точке (onEndReachedThreshold значения onEndReachedThreshold снизу), и он будет выбирать следующие categories и объединяет реквизиты категорий.

Но моя проблема - onEndReached вызывается при вызове render(). Другими словами, FlatList onEndReached запускается до того, как он достигнет дна.

Я помещаю неправильное значение для onEndReachedThreshold? Вы видите какую-то проблему?

return (
  <View style={{ flex:1 }}>
    <FlatList
      data={this.props.categories}
      renderItem={this._renderItem}
      keyExtractor={this._keyExtractor}
      numColumns={2}
      style={{flex: 1, flexDirection: 'row'}}
      contentContainerStyle={{justifyContent: 'center'}}
      refreshControl={
        <RefreshControl
          refreshing = {this.state.refreshing}
          onRefresh = {()=>this._onRefresh()}
        />
      }
      // curent value for debug is 0.5
      onEndReachedThreshold={0.5} // Tried 0, 0.01, 0.1, 0.7, 50, 100, 700

      onEndReached = {({distanceFromEnd})=>{ // problem
        console.log(distanceFromEnd) // 607, 878 
        console.log('reached'); // once, and if I scroll about 14% of the screen, 
                             //it prints reached AGAIN. 
        this._onEndReachedThreshold()
      }}
    />
  </View>
)

ОБНОВЛЕНИЕ Я получаю данные this.props.categories здесь

  componentWillMount() {
    if(this.props.token) {
      this.props.loadCategoryAll(this.props.token);
    }
  }

Ответ 1

Попробуйте реализовать onMomentumScrollBegin в FlatList:

constructor(props) {
    super(props);
    this.onEndReachedCalledDuringMomentum = true;
}

...

<FlatList
    ...
    onEndReached={this.onEndReached.bind(this)}
    onEndReachedThreshold={0.5}
    onMomentumScrollBegin={() => { this.onEndReachedCalledDuringMomentum = false; }}
/>

и измените свой onEndReached

onEndReached = ({ distanceFromEnd }) => {
    if(!this.onEndReachedCalledDuringMomentum){
        this.fetchData();
        this.onEndReachedCalledDuringMomentum = true;
    }
}

Ответ 2

Сначала проверьте, находится ли FlatList внутри ScrollView или Content native-base. Тогда возьми это вне этого На самом деле вам не нужно использовать Content или ScrollView, поскольку FlatList имеет как ListFooterComponent, так и ListHeaderComponent.

Хотя это не рекомендуется, если вам действительно нужно использовать Flatlist внутри ScrollView, взгляните на этот ответ: fooobar.com/questions/16035118/...

Ответ 3

Возможно, вы можете обойти эту ошибку FlatList, увеличивая страницу перед выполнением асинхронного вызова, а затем вы будете получать данные по каждому файлу onEndReached и не будете получать ошибки о дубликатах ключей.

Ответ 4

Удалить каждый прокручиваемый вид из своего FlatList

Ответ 5

Я решил это с помощью debounce от lodash. Во-первых, я импортирую debounce из 'lodash.debounce'. Затем я использую функцию debounce для загрузки дополнительной функции с интервалом 500 мс

<Flatlist onEndReached = {debounce(this._onLoadMore, 500)} />