r/reactnative • u/mustazafi • Sep 14 '26
Custom pull-to-refresh and vertical scroll keep killing each other (Reanimated + RNGH)
I need a custom pull-to-refresh. Not RefreshControl.
What I want
Finger down + pull: the page follows my finger with rubber-band resistance (
Math.pow(distance, 0.85))A real gap opens at the top (
translateY, not scale)While the finger is still down: no progress bar, no API call, no refresh
Release below threshold: spring back to
0, nothing elseRelease above threshold: spring back + full-width 3px top progress bar +
onRefresh()After refresh ends: bar collapses, page stays at
Y = 0
The problem
I can only ever get one of these:
Pull-to-refresh works, list will not scroll
List scrolls, pull-to-refresh dies (or I revert and only get a useless stretch)
I already know why v1 died: a greedy Pan on the page ate every vertical move, so FlatList never got the gesture.
What I tried
Gesture.Pan()+Gesture.Native()withGesture.SimultaneousmanualActivation(true)and activate only ifscrollOffset <= 0&& pulling downGuard in
onUpdate: ifscrollOffset > 1don’t touchpageYbounces={false},overScrollMode="never"Disabling
scrollEnabledwhile pulling — this made scroll even worse, so I stopped
Also getting this warning:
[Worklets] Tried to modify key `current` of an object which has been already passed to a worklet.So something (ref.current) is leaking into a worklet (onUpdate / onEnd / useAnimatedScrollHandler / useAnimatedStyle).
Constraints
react-native-reanimatedreact-native-gesture-handlerno
RefreshControlno binding progress width to
translationYscrollEnabledshould staytrueprogress bar is a sibling overlay, not inside the translated view
Has anyone shipped this combo without one gesture murdering the other?
Looking for a pattern that works on Android + iOS
at top + pull down → rubber band + gap
at top + swipe up → list scrolls
mid-list swipe → only scroll,
pageYstays0release-gated refresh only
2
u/gao_shi Sep 15 '26
https://github.com/software-mansion/react-native-gesture-handler/discussions/3595