【问题标题】:React Native: You have a large list that is slow to updateReact Native:你有一个更新缓慢的大列表
【发布时间】:2022-01-16 14:06:05
【问题描述】:

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

VirtualizedList:您有一个更新缓慢的大型列表 - 确保您的 renderItem 函数呈现遵循 React 性能最佳实践的组件,例如 PureComponent、shouldComponentUpdate 等。 Object { “内容长度”: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 &amp;&amp; &lt;ActivityIndicator animating={isLoadingMore} /&gt;})。将其更改为 ListFooterComponent={&lt;ActivityIndicator animating={isLoadingMore} /&gt; 即可解决此问题。 @parse 已打开一个问题(请参阅下面的 cmets),可以在 here 找到。

【问题讨论】:

    标签: react-native pagination react-native-flatlist react-memo


    【解决方案1】:

    在我的情况下,这是因为 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} 
    

    【讨论】:

    • 嗨,我已经实现了这个逻辑,正如你在代码if (!isLoadingMore &amp;&amp; hasMoreToFetch) { onEndReached(); } 中看到的那样,这只会调用传递给NewsListonEndReached 函数,前提是它还没有加载更多并且有获取更多数据。另外,对于initialNumToRender,如果我不确切知道我从 API 中获得了多少新闻文章,我该怎么做?
    • 使用名为 removeClippedSubviews 和 initialNumToRender 的道具 何时使用 initialNumberToRender 如果有分页,您获得 50 条数据 那时我建议使用此道具,使用 removeClippedSubViews 会更有效
    • onEndReachedThreshold 也非常有用,因为道具描述了当内容对屏幕半可见时,它将调用 onEndReached 函数。这个属性的设置值也有助于提高滚动效果。
    • @VinitBhavsar 在 Android 上 - 我正在测试并看到错误的设备, removeClippedSubviews 默认为 true。我也尝试过 initialNumToRender 道具。没有运气。
    • 尝试将ListFooterComponent={hasMoreToFetch &amp;&amp; &lt;ActivityIndicator animating={isLoadingMore} /&gt;} 更改为ListFooterComponent={&lt;ActivityIndicator animating={isLoadingMore} /&gt;},如果可行,请告诉我!就我而言,我调试了一整天,发现当 footer prop 没有状态时,它可以正常工作而没有警告。
    猜你喜欢
    • 2021-12-06
    • 2017-11-28
    • 2018-01-13
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 2018-10-24
    相关资源
    最近更新 更多