Shopify / Shopify/flash-list

ListEmptyComponent flashes briefly and disappears on iOS when data is empty (New Architecture)

Open
#2,089 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug P1
Dominant language
TypeScript
Stars
7.2k
Forks
393
Avg merge
1d 3h
Merged PRs (30d)
1

Description

**Description**

  • When using FlashList with empty data, the ListEmptyComponent is rendered only for a brief moment and then disappears on iOS.
  • This issue does not occur on Android — Android behaves as expected and keeps the ListEmptyComponent visible.

Environment

  • @shopify/flash-list: ^2.1.0
  • react-native: ^0.82.0
  • New Architecture: Enabled

Platform:

  • iOS: ❌ Issue present
  • Android: ✅ Works fine

Expected Behavior
When the data prop is an empty array, ListEmptyComponent should remain visible until data is provided, on both iOS and Android.

Actual Behavior
On iOS:

  • ListEmptyComponent appears briefly (for a second)
  • Then disappears automatically
  • No further renders occur until data changes

On Android:

  • Works correctly
  • ListEmptyComponent stays visible

Sample Code Issue is Getting reproduced :
<Flashlist data={isInitialLoading ? dummyData : data} ref={listRef} alwaysBounceVertical={false} viewabilityConfigCallbackPairs={enableFeedAnalytics ? viewabilityConfigCallbackPairs.current : null} onViewableItemsChanged={combinedViewabilityCallback} // contentContainerStyle={listContainerStyle} refreshControl={ getData ? ( <RefreshControl refreshing={loadReason === LOAD_REASON.REFRESH} onRefresh={() => { setLoadReason(LOAD_REASON.REFRESH); onHomeRefresh?.(); getPage(1); extraLoadingParams?.(); }} /> ) : null } getItemType={getItemType} viewabilityConfig={viewabilityConfig} onEndReachedThreshold={endReachedThreshhold} onEndReached={onEndReached} keyExtractor={loadingLocation === LOADING_LOCATION_TOP ? (item) => item.toString() : keyExtractor} ListHeaderComponentStyle={ListHeaderStyle} removeClippedSubviews={true} // bounces={false} bouncesZoom={false} ListFooterComponent={ <> {loadingLocation === LOADING_LOCATION_BOTTOM ? loaderComponent() : null} {data.length > 0 && loadingLocation === LOADING_LOCATION_NOTHING ? ( <View style={styles.itemSeparator} /> ) : null} {loadingLocation === LOADING_LOCATION_NOTHING && isPaginationDone.current && data.length && ![LoggedInRouteNames.IndividualPost, LoggedInRouteNames.PrayerRequestDetail].includes(route.name) ? ( <MyText style={styles.notificationDoneMsg}>{t('feedListing.endOfFeed')}</MyText> ) : null} </> } ListHeaderComponent={headerComponent} ItemSeparatorComponent={({ leadingItem, trailingItem }) => { const { isPrayerUpdateOrTest, isWithoutFeed, isWithFeed, isPrayerFeed, isGlobalNews, isEvent, isHorizontalEventCard, isPoll, } = getFeedItemType(trailingItem, 1); const isLoading = loadingLocation === LOADING_LOCATION_TOP; if ( !isPoll && !isLoading && !isPrayerUpdateOrTest && !isWithoutFeed && !isWithFeed && !isPrayerFeed && !isGlobalNews && !isEvent && !isHorizontalEventCard ) { return null; } else { return <View style={styles.itemSeparator} />; } }} ListEmptyComponent={() => loadingLocation === LOADING_LOCATION_NOTHING && !data.length && !isGroupAbout ? ( <FeedEmptyComponent icon={ImageFolderYellow} text={empty_text} testID={testID} /> ) : null } renderItem={renderItem} onScroll={(e) => { if (data && data.length > 0) { onScroll?.(e); } }} />

Issue reproducing video attached:
https://github.com/user-attachments/assets/64d1a256-14b0-40a6-94d6-27c9853fea35

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the attached FlashList usage on iOS with React Native 0.82 and the New Architecture enabled, using an empty data array and ListEmptyComponent. Start by tracing how the empty component is rendered, then verify that it remains visible until data is provided and that the Android behavior remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
react-native, typescript
Domain
mobile
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.