You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FlashList滚动复用项时显示加载器/骨架屏方案咨询

解决方案

一、解决返回顶部卡片重渲染问题

问题根源在于使用index作为列表项的key,当列表滚动或数据变动时,index会发生变化,导致FlashList销毁旧组件并重建新组件。将key替换为帖子唯一标识item.feed_id即可稳定组件身份,避免不必要的重渲染:

// 在renderItem中修改FeedsCardLayout的key属性
<FeedsCardLayout
  key={item.feed_id} // 替换原有的key={index}
  showEdit={diff}
  // 其他属性保持不变
/>

二、解决快速滚动出现空白的问题

通过优化FlashList配置+添加占位加载组件(Shimmer)填补渲染间隙:

1. 优化FlashList渲染配置

添加getItemLayout属性,提前告知列表每个项的高度,减少动态布局计算时间;调整estimatedItemSize为实际卡片的准确高度,提升滚动流畅性:

// 在FlashList组件中添加getItemLayout
<FlashList
  data={feedList}
  renderItem={renderItem}
  ListFooterComponent={renderFooter}
  // 添加getItemLayout
  getItemLayout={(data, index) => ({
    length: 362, // 替换为卡片实际高度,和estimatedItemSize一致
    offset: 362 * index,
    index,
  })}
  estimatedItemSize={362} // 确保和实际卡片高度匹配
  // 其他属性保持不变
/>

2. 添加Shimmer占位组件

第一步:创建Shimmer占位组件

// 可单独创建组件文件,或直接在当前文件中定义
const ShimmerCard = ({ colors }) => {
  return (
    <View style={{
      height: 362,
      marginBottom: wp(10),
      backgroundColor: colors.grey,
      borderRadius: wp(10),
      padding: wp(15),
    }}>
      <View style={{
        height: hp(5),
        width: wp(30),
        backgroundColor: colors.lightGrey,
        borderRadius: wp(5),
        marginBottom: wp(10),
      }} />
      <View style={{
        height: hp(20),
        width: '100%',
        backgroundColor: colors.lightGrey,
        borderRadius: wp(10),
        marginBottom: wp(10),
      }} />
      <View style={{
        flexDirection: 'row',
        justifyContent: 'space-between',
      }}>
        <View style={{
          height: hp(4),
          width: wp(25),
          backgroundColor: colors.lightGrey,
          borderRadius: wp(5),
        }} />
        <View style={{
          height: hp(4),
          width: wp(20),
          backgroundColor: colors.lightGrey,
          borderRadius: wp(5),
        }} />
      </View>
    </View>
  );
};

第二步:在renderItem中集成占位逻辑

根据实际数据就绪状态判断,未加载完成时显示Shimmer:

const renderItem = ({ item, index }) => {
  const endDate = moment(item.created_at).add(5, 'hours').add(45, 'minutes');
  const todaysdate = moment();
  const diff = endDate > todaysdate;
  
  // 可根据实际数据(如视频/图片是否加载完成)调整判断条件
  const isLoading = !item?.content || !item?.created_at;

  if (isLoading) {
    return <ShimmerCard colors={colors} />;
  }

  return (
      <FeedsCardLayout
        key={item.feed_id}
        showEdit={diff}
        callback={() => {
          callback(item.feed_id);
        }}
        residentId={residentId}
        data={item}
        bottomCallback={(callbackType, data) => {
          bottomCallback(callbackType, data, index);
        }}
        shareCallback={shareCallback}
        pollCallback={(selectedOption, pollData) => {
          pollCallback(selectedOption, pollData, index);
        }}
        menuCallback={callbackType => {
          menuCallback(callbackType, item, index);
        }}
      />
  );
};

额外优化建议

  • 调整maxToRenderPerBatch和initialNumToRender:将initialNumToRender设为屏幕可见卡片数(比如2),减少初始渲染压力
  • 对FeedsCardLayout中的媒体资源(视频、图片)添加懒加载和缓存,避免重复加载
  • 确保feedList数据稳定性,避免频繁修改数组引用(使用immutable数据或浅拷贝更新)

内容的提问来源于stack exchange,提问作者PRANESH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 16:54:55