We are experiencing a reproducible Android crash when using FlashList with the New Architecture (Fabric enabled) under rapid data reordering while scrolling.
This issue occurs when the user pins or unpins a post and then quickly scrolls the list.
The crash happens on the UI thread during view traversal, with the following exception:
IllegalStateException: EdgeToEdgeReactViewGroup contains null child at index X
when traversal in dispatchGetDisplayList, the view may have been removed.
This issue only occurs on Android, only with Fabric enabled
Environment
• Library: "@shopify/flash-list": "2.2.0",
• Platform: Android
• Architecture: New Architecture (Fabric enabled)
• Edge-to-Edge: Enabled
• React Native: 0.81.4 /~54.0.31 (Fabric ON)
• Reanimated: 4.1.3
• Gesture Handler: ~2.28.0
import { FlashList, FlashListProps, FlashListRef } from "@shopify/flash-list"
import React, { memo, ReactElement, RefObject, useMemo } from "react"
import { type ViewToken } from "react-native"
import Animated, { AnimatedProps } from "react-native-reanimated"
import { RefreshComponent } from "src/components/atoms/feed/RefreshComponent"
import { usePagerContext } from "src/components/profile/tab-view/PagerContext"
import { useRefresh } from "src/hooks/app/useRefresh"
import { useFindScrollViewTag } from "src/hooks/scroll/useFindScrollViewTag"
type PagerFlashListProps<T> = Omit<
FlashListProps<T>,
| "onMomentumScrollBegin" // Use ScrollContext instead.
| "onMomentumScrollEnd" // Use ScrollContext instead.
| "onScroll" // Use ScrollContext instead.
| "onScrollBeginDrag" // Use ScrollContext instead.
| "onScrollEndDrag" // Use ScrollContext instead.
| "refreshControl" // Pass refreshing and/or onRefresh instead.
| "contentOffset" // Pass headerOffset instead.
| "progressViewOffset" // Can't be an animated value
| "onRefresh"
| "refreshing"
> & {
readonly onRefresh?: () => Promise<unknown>
readonly onItemSeen?: (item: T) => void
readonly progressViewOffset?: number
}
const AnimatedFlashList = Animated.createAnimatedComponent(FlashList) as <T>(
props: AnimatedProps<
FlashListProps<T> & {
ref?: React.Ref<FlashListRef<T>> | undefined
}
>
) => ReactElement
const PagerFlashList_Unmemo = <T,>({
onRefresh: _onRefresh,
onItemSeen,
style,
progressViewOffset,
automaticallyAdjustsScrollIndicatorInsets = false,
...props
}: PagerFlashListProps<T>) => {
const {
scrollHandler,
isFocused,
setScrollViewTag,
scrollElRef: ref,
headerHeight: headerOffset
} = usePagerContext()
useFindScrollViewTag({
isFocused,
scrollRef: ref,
setScrollViewTag
})
const [onViewableItemsChanged, viewabilityConfig] = useMemo(() => {
if (!onItemSeen) {
return [undefined, undefined]
}
return [
(info: { viewableItems: ViewToken<T>[]; changed: ViewToken<T>[] }) => {
for (const item of info.changed) {
if (item.isViewable) {
onItemSeen(item.item)
}
}
},
{
itemVisiblePercentThreshold: 40,
minimumViewTime: 0.5e3
}
]
}, [onItemSeen])
const { onRefresh, isRefreshing } = useRefresh({ refetch: _onRefresh })
return (
<AnimatedFlashList
onViewableItemsChanged={onViewableItemsChanged}
showsVerticalScrollIndicator={false}
viewabilityConfig={viewabilityConfig}
{...props}
automaticallyAdjustsScrollIndicatorInsets={
automaticallyAdjustsScrollIndicatorInsets
}
contentContainerStyle={{
paddingTop: headerOffset,
paddingBottom: headerOffset * 1.5
}}
maintainVisibleContentPosition={{ disabled: true }}
onScroll={scrollHandler}
ref={ref as RefObject<FlashListRef<T> | null> | undefined}
refreshControl={
_onRefresh ? (
<RefreshComponent
onRefresh={onRefresh}
progressViewOffset={progressViewOffset ?? headerOffset}
refreshing={isRefreshing}
/>
) : undefined
}
scrollEventThrottle={isFocused ? 16 : undefined}
scrollsToTop
style={style}
/>
)
}
export const PagerFlashList = memo(
PagerFlashList_Unmemo
) as typeof PagerFlashList_Unmemo
We are experiencing a reproducible Android crash when using FlashList with the New Architecture (Fabric enabled) under rapid data reordering while scrolling.
This issue occurs when the user pins or unpins a post and then quickly scrolls the list.
The crash happens on the UI thread during view traversal, with the following exception:
This issue only occurs on Android, only with Fabric enabled
Environment
• Library: "@shopify/flash-list": "2.2.0",
• Platform: Android
• Architecture: New Architecture (Fabric enabled)
• Edge-to-Edge: Enabled
• React Native: 0.81.4 /~54.0.31 (Fabric ON)
• Reanimated: 4.1.3
• Gesture Handler: ~2.28.0