Is your feature request related to a problem? Please describe.
We migrated a vertical full-page reel feed (TikTok/Reels style) from FlashList / FlatList to react-native-reanimated-carousel v5.1.1.
Two FlatList-level APIs are missing, and the current v5 surface cannot replace them without fragile workarounds:
1. Pull-to-refresh (FlatList RefreshControl)
v5 has no refreshControl, onRefresh, or refreshing prop.
overscrollEnabled only rubber-bands and snaps back. It does not:
- detect a pull past a threshold on the first item
- call a refresh handler
- keep a spinner visible while
refreshing === true
onConfigurePanGesture is not a real replacement:
CarouselPanGesture is a facade that blocks runOnJS, enabled, and manualActivation
- JS side effects must use
scheduleOnRN
- carousel-owned pan handlers run before consumer observers, so overscroll rebound fights the pull
- there is no first-class “at index 0 + pulling backward” state
- there is no built-in refresh indicator
Result: pull-to-refresh on a vertical carousel is custom, easy to break, and does not match FlatList UX.
2. onScroll (FlatList onScroll / NativeScrollEvent)
v5 lifecycle is only:
onScrollStart(): void — no offset, velocity, or direction
onSnapToItem(index: number) — fires after settle, not during the gesture
That is not enough for a feed that needs per-frame scroll:
- prefetch the next page while the user is still dragging (not only after snap)
- pause / duck video during the swipe
- analytics (scroll depth, direction, velocity)
- sync UI that is tied to pixel offset (progress bars, sticky chrome)
onProgressChange / progress / scrollOffsetValue are not a drop-in onScroll:
onProgressChange is JS every frame with a logical index, not NativeScrollEvent (contentOffset, velocity, contentSize, layoutMeasurement)
getCurrentIndex() is the last settled index, so it is wrong during an in-flight swipe
scrollOffsetValue is UI-thread / two-way and “does not commit selection or fire onSnapToItem”
- there is no
onScrollBeginDrag / onScrollEndDrag / onMomentumScrollEnd equivalent with payload
So a FlashList feed that used onScroll + RefreshControl cannot be moved to v5 without reimplementing both.
Describe the solution you'd like
A. First-class pull-to-refresh
Support the FlatList mental model on a non-loop carousel, especially orientation="vertical":
<Carousel
data={items}
orientation="vertical"
loop={false}
refreshing={isRefreshing}
onRefresh={() => refetch()}
refreshControl={
<RefreshControl
refreshing={isRefreshing}
onRefresh={refetch}
tintColor="#fff"
/>
}
renderItem={renderItem}
/>
Is your feature request related to a problem? Please describe.
We migrated a vertical full-page reel feed (TikTok/Reels style) from
FlashList/FlatListtoreact-native-reanimated-carouselv5.1.1.Two FlatList-level APIs are missing, and the current v5 surface cannot replace them without fragile workarounds:
1. Pull-to-refresh (FlatList
RefreshControl)v5 has no
refreshControl,onRefresh, orrefreshingprop.overscrollEnabledonly rubber-bands and snaps back. It does not:refreshing === trueonConfigurePanGestureis not a real replacement:CarouselPanGestureis a facade that blocksrunOnJS,enabled, andmanualActivationscheduleOnRNResult: pull-to-refresh on a vertical carousel is custom, easy to break, and does not match FlatList UX.
2.
onScroll(FlatListonScroll/NativeScrollEvent)v5 lifecycle is only:
onScrollStart(): void— no offset, velocity, or directiononSnapToItem(index: number)— fires after settle, not during the gestureThat is not enough for a feed that needs per-frame scroll:
onProgressChange/progress/scrollOffsetValueare not a drop-inonScroll:onProgressChangeis JS every frame with a logical index, notNativeScrollEvent(contentOffset,velocity,contentSize,layoutMeasurement)getCurrentIndex()is the last settled index, so it is wrong during an in-flight swipescrollOffsetValueis UI-thread / two-way and “does not commit selection or fireonSnapToItem”onScrollBeginDrag/onScrollEndDrag/onMomentumScrollEndequivalent with payloadSo a FlashList feed that used
onScroll+RefreshControlcannot be moved to v5 without reimplementing both.Describe the solution you'd like
A. First-class pull-to-refresh
Support the FlatList mental model on a non-loop carousel, especially
orientation="vertical":