在网格和列表视图之间切换反应本地(flatList)每次都会呈现标题

发布于 2025-01-27 19:13:13 字数 2458 浏览 2 评论 0原文

我有一个列表,当我在网格和列表视图之间单击一个按钮时。问题在于我的flatlist我有一个listheaderComponent,每次在两者之间切换时都会呈现,并且我不希望它重新渲染。

另外,我无法将标头放在lactlist外面,因为我需要它滚动,并且无法用scrollview包装所有屏幕。 更改ISGRID时的flatlist rerenders 我该如何解决?

这是我的实现:

flatlist组件

<SafeAreaView style={styles.screen}>
  <FlatList
    ref={flatListRef}
    data={ads}
    numColumns={isGrid ? 2 : 1}
    key={isGrid ? 1 : 0}
    nestedScrollEnabled
    columnWrapperStyle={isGrid ? styles.grid : null}
    initialScrollIndex={0}
    onEndReachedThreshold={0.5}
    onEndReached={onEndReached}
    ListHeaderComponent={Header}
    keyExtractor={(item) => item?._id}
    showsVerticalScrollIndicator={false}
    ListHeaderComponentStyle={HeaderStyle}
    ListFooterComponentStyle={footerStyle || styles.footerStyle}
    renderItem={({ item, index }) =>
      isGrid ? (
        <AdCard
          ad={item}
          onPress={() => goToDetails(item?._id, index)}
          containerStyle={styles.gridCardStyle}
        />
      ) : (
        <AdsCard
          ad={item}
          onPressThreeDot={onPressThreeDot}
          onPress={() => goToDetails(item?._id, index)}
          isList={true}
          containerStyle={styles.adCard}
        />
      )
    }
    ListEmptyComponent={loading ? loadingPlaceholder : noAdsComponent}
    contentContainerStyle={
      isGrid ? styles.gridStyle : styles.contentContainerStyle
    }
    getItemLayout={(d, index) => {
      return isGrid
        ? { length: hp(250), offset: index * hp(250), index }
        : { length: hp(348), offset: index * hp(348), index };
    }}
    ListFooterComponent={<AdsEndMessage isLoading={loading} />}
    refreshControl={
      <RefreshControl
        refreshing={isRefreshing}
        onRefresh={onRefresh}
        tintColor={BURNING_ORANGE}
        colors={[BURNING_ORANGE]}
      />
    }
  />
</SafeAreaView>

标头组件(作为道具传递给flatlist):

<SafeAreaView style={styles.container}>
  {bannerAds?.length > 0 && <BannerAds bannerAds={bannerAds} />}
  <SectionHeader sectionStyle={styles.sectionStyle} />
  <HomeAdsTab />
  <View style={styles.toggleView}>
    <Text style={styles.title}>{t('common.tazweed-marketplace')}</Text>
    <ToggleGridOrList />
  </View>
</SafeAreaView>

提前感谢您

I have a flatlist that when I click a button switches between grid and list view. The problem is in my FlatList I have a ListHeaderComponent which re renders each time I switch between the two and I don't want it to re render.

Also, I can't place the Header outside the flatlist since I need it to scroll and I can't wrap all screen with a ScrollView
The FlatList rerenders when isGrid is changed
How can I solve it ?

Here is my implementation:

FlatList Component:

<SafeAreaView style={styles.screen}>
  <FlatList
    ref={flatListRef}
    data={ads}
    numColumns={isGrid ? 2 : 1}
    key={isGrid ? 1 : 0}
    nestedScrollEnabled
    columnWrapperStyle={isGrid ? styles.grid : null}
    initialScrollIndex={0}
    onEndReachedThreshold={0.5}
    onEndReached={onEndReached}
    ListHeaderComponent={Header}
    keyExtractor={(item) => item?._id}
    showsVerticalScrollIndicator={false}
    ListHeaderComponentStyle={HeaderStyle}
    ListFooterComponentStyle={footerStyle || styles.footerStyle}
    renderItem={({ item, index }) =>
      isGrid ? (
        <AdCard
          ad={item}
          onPress={() => goToDetails(item?._id, index)}
          containerStyle={styles.gridCardStyle}
        />
      ) : (
        <AdsCard
          ad={item}
          onPressThreeDot={onPressThreeDot}
          onPress={() => goToDetails(item?._id, index)}
          isList={true}
          containerStyle={styles.adCard}
        />
      )
    }
    ListEmptyComponent={loading ? loadingPlaceholder : noAdsComponent}
    contentContainerStyle={
      isGrid ? styles.gridStyle : styles.contentContainerStyle
    }
    getItemLayout={(d, index) => {
      return isGrid
        ? { length: hp(250), offset: index * hp(250), index }
        : { length: hp(348), offset: index * hp(348), index };
    }}
    ListFooterComponent={<AdsEndMessage isLoading={loading} />}
    refreshControl={
      <RefreshControl
        refreshing={isRefreshing}
        onRefresh={onRefresh}
        tintColor={BURNING_ORANGE}
        colors={[BURNING_ORANGE]}
      />
    }
  />
</SafeAreaView>

Header Component (passed as a prop to the flatlist):

<SafeAreaView style={styles.container}>
  {bannerAds?.length > 0 && <BannerAds bannerAds={bannerAds} />}
  <SectionHeader sectionStyle={styles.sectionStyle} />
  <HomeAdsTab />
  <View style={styles.toggleView}>
    <Text style={styles.title}>{t('common.tazweed-marketplace')}</Text>
    <ToggleGridOrList />
  </View>
</SafeAreaView>

Thank you in Advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

半衬遮猫 2025-02-03 19:13:13

经过大量研究,没有解决方案……我很自豪地说我已经发现了一项很好的工作。基本上,您所拥有的东西是将numcolumns设置为某些静态变量的。在我的情况下,我将其设置为2。然后使用columnWrapperStyle,然后根据可以设置的某些状态切换flexDirection

这样的事情:

numColumns={2}
contentContainerStyle={contentContainerStyle}
renderItem={renderItem}
columnWrapperStyle={{ flexDirection: !showCollectables ? 'column' : 'row' } as ViewStyle }

After a lot of research and no solution... I am proud to say I have discovered a pretty good work around. Basically what you have todo is set numColumns to some static variable. In my case I set it to 2. Then use columnWrapperStyle and switch the flexDirection based on some state you can set.

Something like this:

numColumns={2}
contentContainerStyle={contentContainerStyle}
renderItem={renderItem}
columnWrapperStyle={{ flexDirection: !showCollectables ? 'column' : 'row' } as ViewStyle }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文