0

我正在尝试使用 FlatList 在 React Native 中实现分页。我遵循了最佳实践,但我仍然收到以下错误:

VirtualizedList:您有一个更新缓慢的大型列表 - 确保您的 renderItem 函数呈现遵循 React 性能最佳实践的组件,如 PureComponent、shouldComponentUpdate 等。 Object { "contentLength": 23651.732421875, "dt": 1394, "prevDt" : 865, }

这是代码:

const NewsScreen = ({ isLoading, news, fetchInitialNews, fetchMoreNews, isLoadingMore, hasMoreToFetch }) => {
 
  useEffect(() => {
    fetchInitialNews();
  }, []);

  const onEndReached = () => {
    fetchMoreNews();
  };

  return (
      <NewsList
        isLoading={isLoading}
        news={news}
        numSkeletonsToShow={LATEST_NEWS_CONSTANTS.NUM_TO_SHOW}
        contentContainerStyle={STYLES.newsListContentContainer}
        onEndReached={onEndReached}
        isLoadingMore={isLoadingMore}
        hasMoreToFetch={hasMoreToFetch}
      />
  );
};
const renderNewsItem = ({ item, index }) => (
  <NewsItem news={item} containerStyle={index !== 0 ? GLOBAL_STYLES.cardMargin : null} />
);

const NewsList = ({
  isLoading,
  news = [],
  isLoadingMore,
  contentContainerStyle = {},
  onEndReached,
  hasMoreToFetch
}) => {
  const dummySkeletonArray = Array(numSkeletonsToShow).fill("1");

  const onScrollToEnd = () => {
    if (!isLoadingMore && hasMoreToFetch) {
      onEndReached();
    }
  };

  if (isLoading) {
    return (
      //..loading indicator
    );
  }

  return (
    <FlatList
      data={news}
      keyExtractor={(n) => n.url}
      renderItem={renderNewsItem}
      showsVerticalScrollIndicator={false}
      style={GLOBAL_STYLES.flatListContentContainer}
      contentContainerStyle={contentContainerStyle}
      onEndReached={onScrollToEnd}
      onEndReachedThreshold={0.2}
      ListFooterComponent={hasMoreToFetch && <ActivityIndicator animating={isLoadingMore} />}
    />
  );
};
const areEqual = () => true;

const NewsItem = ({ news, containerStyle }) => {
  return (
    <TouchableNativeFeedback viewContainerStyle={containerStyle}>
      <Card>
      </Card>
    </TouchableNativeFeedback>
  );
};

export default memo(NewsItem, areEqual);

正如许多其他帖子所建议的那样,我已经使用memo并移动了renderItem功能组件的外部。仍然没有运气。谢谢您的帮助!

更新:

问题是由于有条件地渲染ListFooterComponent(即ListFooterComponent={hasMoreToFetch && <ActivityIndicator animating={isLoadingMore} />})。更改它以ListFooterComponent={<ActivityIndicator animating={isLoadingMore} />解决问题。@parse 已经打开了一个问题(请参阅下面的评论),可以在这里找到。

4

1 回答 1

0

就我而言,这是因为OnEndReached被多次调用。由于您正在尝试从服务器获取下一组数据,因此如果一次调用 onEndReached 多次,它会尝试多次从服务器调用。我通过有一个状态来避免多次调用来解决:

const [loader, setLoader] = useState(false);

const onEndReached = (page) => {
  if (!loader) {
    setPage(page + 1)
  }
}

const loadData = async () => {
  setLoader(true);
  const resp = await fetchMoreNews();
  setLoader(false);
}

<FlatList ...someprops onEndReached={onEndReached} />

在其他一些情况下,将以下代码添加到您的 Flatlist 也可以,其中 n 是一个小数字(在我的情况下为 10)。

initialNumToRender={n} 
于 2022-01-16T14:22:38.280 回答