Shopify / flash-list

A better list for React Native
https://shopify.github.io/flash-list/
MIT License
5.36k stars 276 forks source link

Sticky Header Re-renders and Flickers When Becoming Sticky #1242

Open D-Mass-RR opened 2 months ago

D-Mass-RR commented 2 months ago

Current behavior

https://github.com/Shopify/flash-list/assets/75733398/fba844e7-dae7-4ea0-9c2e-782d9a47d72f

Expected behavior

The sticky header should smoothly become sticky without re-rendering or causing any flickering.

To Reproduce

render item

const renderItem = ({
    item,
    index,
  }: {
    item: FoodData;
    index: number;
    target: RenderTarget;
  }) => {
    if (index === 0) {
      return <CategoriesSlider />;
    } else
      return (
        <>
          <View style={styles.innerContainer}>
            <AppText.H2
              style={[index === 1 ? styles.MT20 : styles.MT30, styles.MB20]}
            >
              {item.category_name}
            </AppText.H2>
            {item.items.map((item: Omit<Food, "count">) => (
              // eslint-disable-next-line react/jsx-key
              <FoodCardLarge
                onAddToCart={onAddToCart}
                onPressCard={() => onPressCard(item.id)}
                {...item}
              />
            ))}
            <View style={styles.divider}>
              <Divider />
            </View>
          </View>
        </>
      );
  };

flash list

// Render
  return (
    <>
      <SafeAreaView style={styles.container}>
        <LanguageModal onClose={() => setLangModal(false)} isOpen={langModal} />
        <FlashList
          stickyHeaderHiddenOnScroll
          estimatedFirstItemOffset={10}
          invertStickyHeaders
          onViewableItemsChanged={onViewableItemsChanged}
          ListHeaderComponentStyle={styles.innerContainer}
          contentContainerStyle={styles.content}
          ListHeaderComponent={renderHeader()}
          estimatedItemSize={300}
          renderItem={renderItem}
          estimatedListSize={{
            width: Dimensions.get("screen").width - size(20),
            height: height(80),
          }}
          data={data}
          extraData={data.length}
          stickyHeaderIndices={[0]}
          keyExtractor={keyExtractor}
          showsVerticalScrollIndicator={false}
        />
        <Toast topOffset={70} config={toastConfig} visibilityTime={1500} />
      </SafeAreaView>
    </>
  );

Platform:

Environment

"react-native-gesture-handler": "^2.16.1", "react-native-reanimated": "^3.10.0", "@shopify/flash-list": "^1.6.4", "react-native": "0.74.0",

D-Mass-RR commented 1 month ago

@naqvitalha