Flatlist с вызовом API при прокрутке не работает должным образом - PullRequest
0 голосов
/ 09 мая 2020

Я использую функциональный компонент в react native. В этом случае я использую Flatlist для просмотра данных. в функции onEndReached FlatList я вызываю API для получения данных. Моя проблема:

  • при вызове API прокрутки дважды несколько раз
  • на Fini sh всех данных. ActivityIndicator отображается в функции ListFooterComponent.

Не могли бы вы мне помочь. Заранее спасибо.

Вот мой код:

import React, { useState, useEffect } from "react";
import {
  View,
  StyleSheet,
  ActivityIndicator,
  Image,
  FlatList,
  TouchableHighlight,
} from "react-native";

import MainStyle from "../constants/Style";
import Layout from "../constants/Layout";
import Colors from "../constants/Colors";

import Services from "../Services";

const LIMIT_PER_PAGE = 10;
let fetching = false;
let isSubscribed = true;
let isListEnd = false;
let pageNo = 1;
var sortby = "latest";

let width = Layout.window.width / 2 - 16;

export default function PostListScreen(props) {

  const [posts, setPosts] = useState([]);

  fetchAllLatestPost = function () {
    console.log("fetchAllLatestPost", fetching, isListEnd);
    if (!fetching && !isListEnd) {
      fetching = true;
      Services.getAllPost(sortby, pageNo, LIMIT_PER_PAGE)
        .then(function (res) {
          if (!!res) {
            console.log("res.length", res.length)
            if (!!res.length && isSubscribed) {
              pageNo++;
              setPosts((posts) => {
                posts = [...posts, ...res];
                return posts;
              });
            } else {
              isListEnd = true;
            }
            fetching = false;
          }
        });
    }
  };

  useEffect(() => {
    fetching = false;
    isListEnd = false;
    pageNo = 1;
    isSubscribed = true;
    fetchAllLatestPost();
    return () => (isSubscribed = false);
  }, []);

  let readyImage = function (post) {
    if (!!post.urls && !!post.urls.regular) {
      return typeof post.urls.regular === "string"
        ? { uri: post.urls.regular }
        : post.urls.regular;
    } else {
      return require("../assets/images/logo_white.png");
    }
  };

  let renderItem = function (post, index) {
    return (
      <TouchableHighlight onPress={() => onPressPost(post)} key={index}>
        <View style={styles.item}>
          <Image
            source={readyImage(post)}
            style={{
              flex: 1,
              width: null,
              height: null,
              resizeMode: "cover",
              borderRadius: 4,
            }}
          />
        </View>
      </TouchableHighlight>
    );
  };

  let renderFooter = function () {
    return (
      <View style={styles.footer}>
        {console.log("fetching in footer ", fetching)}
        {!!fetching ? (
          <ActivityIndicator color="white" style={{ margin: 15 }} />
        ) : null}
      </View>
    );
  };

  return (
    <View style={MainStyle.wrapper}>
      <FlatList
        numColumns={2}
        keyExtractor={(item, index) => index.toString()}
        data={posts}
        onEndReached={() => fetchAllLatestPost()}
        onEndReachedThreshold={0.5}
        renderItem={({ item, index }) => <View>{renderItem(item, index)}</View>}
        getItemLayout={(data, index) => ({
          length: width,
          offset: (width/2) * index,
          index,
        })}
        ListFooterComponent={renderFooter()}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flexDirection: "row",
    flexWrap: "wrap",
  },
  item: {
    height: width,
    width: width,
    margin: 8,
  },
  footer: {
    padding: 10,
    justifyContent: "center",
    alignItems: "center",
    flexDirection: "row",
  },
});

1 Ответ

1 голос
/ 09 мая 2020

Вот как я с этим справился

<FlatList
        data={this.state.posts}
        onRefresh={() => {
          if (!this.props.posts.fetching) {
            this.setState({
              page: 1,
              checkData: true,
              posts: [],
            });
            this.props.postsRequest({page: 1});
          }
        }}
        // onEndReached={}
        keyExtractor={item => item.uid}
        onMomentumScrollEnd={() => {
          if (!this.props.posts.fetching) {
            this.props.postsRequest({page: this.state.page + 1});
            this.setState({page: this.state.page + 1, checkData: true});
          }
        }}
        onEndReachedThreshold={0}
        refreshing={this.props.posts.fetching}
        showsVerticalScrollIndicator={false}
        contentContainerStyle={{paddingBottom: 50}}
        style={{padding: 10, marginVertical: 10}}
        renderItem={item => (
          <View style={{marginVertical: 5}}>
            <Posts post={item.item} navigation={this.props.navigation} />
          </View>
        )}
      />
...