Gesture error when applying pagination
Describe the bug I copied the parallax horizontal code. It doesn't work but when I removed the pagination the carousel works. And I want to use the pagination
To Reproduce Steps to reproduce the behavior:
- Copy the code
import * as React from "react";
import { Dimensions, Text, View } from "react-native";
import { useSharedValue } from "react-native-reanimated";
import Carousel, {
ICarouselInstance,
Pagination,
} from "react-native-reanimated-carousel";
const data = [...new Array(6).keys()];
const width = Dimensions.get("window").width;
function App() {
const ref = React.useRef<ICarouselInstance>(null);
const progress = useSharedValue<number>(0);
const onPressPagination = (index: number) => {
ref.current?.scrollTo({
count: index - progress.value,
animated: true,
});
};
return (
<View style={{ flex: 1 }}>
<Carousel
ref={ref}
width={width}
height={width / 2}
data={data}
onProgressChange={progress}
renderItem={({ index }) => (
<View
style={{
flex: 1,
borderWidth: 1,
justifyContent: "center",
}}
>
<Text style={{ textAlign: "center", fontSize: 30 }}>{index}</Text>
</View>
)}
/>
<Pagination.Basic
progress={progress}
data={data}
dotStyle={{ backgroundColor: "rgba(0,0,0,0.2)", borderRadius: 50 }}
containerStyle={{ gap: 5, marginTop: 10 }}
onPress={onPressPagination}
/>
</View>
);
}
export default App;
- It will show this error
Error: NativeViewGestureHandler must be used as a descendant of GestureHandlerRootView. Otherwise the gestures will not be recognized. See https://docs.swmansion.com/react-native-gesture-handler/docs/installation for more details.
This error is located at:
in NativeViewGestureHandler (created by RNGestureHandlerButton)
in RNGestureHandlerButton (created by BaseButton)
in BaseButton (created by GenericTouchable)
in GenericTouchable
in Unknown (created by Basic)
in RCTView (created by View)
in View (created by Basic)
in Basic (created by App)
in RCTView (created by View)
in View (created by App)
in App (created by AuthIndex)
in RCTView (created by View)
in View (created by ThemedView)
in ThemedView (created by AuthIndex)
in AuthIndex
in Unknown (created by Route(index))
in Suspense (created by Route(index))
in Route (created by Route(index))
in Route(index) (created by SceneView)
in StaticContainer
in EnsureSingleNavigator (created by SceneView)
in SceneView (created by SceneView)
in RCTView (created by View)
in View (created by DebugContainer)
in DebugContainer (created by MaybeNestedStack)
in MaybeNestedStack (created by SceneView)
in RCTView (created by View)
in View (created by SceneView)
in RNSScreen (created by Animated(Anonymous))
in Animated(Anonymous) (created by InnerScreen)
in Suspender (created by Freeze)
in Suspense (created by Freeze)
in Freeze (created by DelayedFreeze)
in DelayedFreeze (created by InnerScreen)
in InnerScreen (created by Screen)
in Screen (created by SceneView)
in SceneView (created by NativeStackViewInner)
in Suspender (created by Freeze)
in Suspense (created by Freeze)
in Freeze (created by DelayedFreeze)
in DelayedFreeze (created by ScreenStack)
in RNSScreenStack (created by ScreenStack)
in ScreenStack (created by NativeStackViewInner)
in NativeStackViewInner (created by NativeStackView)
in RCTView (created by View)
in View (created by SafeAreaProviderCompat)
in SafeAreaProviderCompat (created by NativeStackView)
in NativeStackView (created by NativeStackNavigator)
in PreventRemoveProvider (created by NavigationContent)
in NavigationContent
in Unknown (created by NativeStackNavigator)
in NativeStackNavigator
in Unknown (created by AuthLayout)
in RNCSafeAreaView
in Unknown (created by AuthLayout)
in AuthLayout
in Unknown (created by Route(auth))
in Suspense (created by Route(auth))
in Route (created by Route(auth))
in Route(auth) (created by SceneView)
in StaticContainer
in EnsureSingleNavigator (created by SceneView)
in SceneView (created by SceneView)
in RCTView (created by View)
in View (created by DebugContainer)
in DebugContainer (created by MaybeNestedStack)
in MaybeNestedStack (created by SceneView)
in RCTView (created by View)
in View (created by SceneView)
in RNSScreen (created by Animated(Anonymous))
in Animated(Anonymous) (created by InnerScreen)
in Suspender (created by Freeze)
in Suspense (created by Freeze)
in Freeze (created by DelayedFreeze)
in DelayedFreeze (created by InnerScreen)
in InnerScreen (created by Screen)
in Screen (created by SceneView)
in SceneView (created by NativeStackViewInner)
in Suspender (created by Freeze)
in Suspense (created by Freeze)
in Freeze (created by DelayedFreeze)
in DelayedFreeze (created by ScreenStack)
in RNSScreenStack (created by ScreenStack)
in ScreenStack (created by NativeStackViewInner)
in NativeStackViewInner (created by NativeStackView)
in RCTView (created by View)
in View (created by SafeAreaProviderCompat)
in SafeAreaProviderCompat (created by NativeStackView)
in NativeStackView (created by NativeStackNavigator)
in PreventRemoveProvider (created by NavigationContent)
in NavigationContent
in Unknown (created by NativeStackNavigator)
in NativeStackNavigator
in Unknown (created by RootLayout)
in ThemeProvider (created by RootLayout)
in QueryClientProvider (created by RootLayout)
in RootLayout
in Unknown (created by Route())
in Suspense (created by Route())
in Route (created by Route())
in Route() (created by ContextNavigator)
in RNCSafeAreaProvider (created by SafeAreaProvider)
in SafeAreaProvider (created by wrapper)
in wrapper (created by ContextNavigator)
in EnsureSingleNavigator
in BaseNavigationContainer
in ThemeProvider
in NavigationContainerInner (created by ContextNavigator)
in ContextNavigator (created by ExpoRoot)
in ExpoRoot (created by App)
in App (created by ErrorOverlay)
in ErrorToastContainer (created by ErrorOverlay)
in ErrorOverlay (created by withDevTools(ErrorOverlay))
in withDevTools(ErrorOverlay)
in RCTView (created by View)
in View (created by AppContainer)
in RCTView (created by View)
in View (created by AppContainer)
in AppContainer
in main(RootComponent), js engine: hermes
- Delete the <Pagination.Basic />
- Carousel works but pagination gone
Expected behavior Both Carousel and Pagination working
Screenshots If applicable, add screenshots to help explain your problem.
Versions (please complete the following information): "expo": "~51.0.28", "react": "18.2.0", "react-native": "0.74.5", "react-native-gesture-handler": "~2.16.1", "react-native-reanimated": "~3.10.1", "react-native-reanimated-carousel": "4.0.0-alpha.12",
Smartphone (please complete the following information):
- Device: Samsung A71 [e.g. iPhone6]
- OS: Android 13 [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
Additional context Add any other context about the problem here.
Hey @bil-lekid! I'm here to help you with any bugs, questions, or contributions while you wait for a human maintainer. Let's get to the bottom of this together!
To resolve the "NativeViewGestureHandler must be used as a descendant of GestureHandlerRootView" error when using pagination with the react-native-reanimated-carousel, you need to ensure that the Carousel component is wrapped in a GestureHandlerRootView. This is necessary for the gesture handlers to work correctly.
Here's how you can modify your code to include the GestureHandlerRootView:
import * as React from "react";
import { View } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { useSharedValue } from "react-native-reanimated";
import Carousel, {
ICarouselInstance,
Pagination,
} from "react-native-reanimated-carousel";
import { SBItem } from "../../components/SBItem";
import SButton from "../../components/SButton";
import { ElementsText, window } from "../../constants";
const PAGE_WIDTH = window.width;
const colors = [
"#26292E",
"#899F9C",
"#B3C680",
"#5C6265",
"#F5D399",
"#F1F1F1",
];
function Index() {
const [isVertical, setIsVertical] = React.useState(false);
const [autoPlay, setAutoPlay] = React.useState(false);
const [pagingEnabled, setPagingEnabled] = React.useState<boolean>(true);
const [snapEnabled, setSnapEnabled] = React.useState<boolean>(true);
const progress = useSharedValue<number>(0);
const baseOptions = isVertical
? ({
vertical: true,
width: PAGE_WIDTH * 0.86,
height: PAGE_WIDTH * 0.6,
} as const)
: ({
vertical: false,
width: PAGE_WIDTH,
height: PAGE_WIDTH * 0.6,
} as const);
const ref = React.useRef<ICarouselInstance>(null);
const onPressPagination = (index: number) => {
ref.current?.scrollTo({
count: index - progress.value,
animated: true,
});
};
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<View
style={{
alignItems: "center",
}}
>
<Carousel
ref={ref}
{...baseOptions}
style={{
width: PAGE_WIDTH,
}}
loop
pagingEnabled={pagingEnabled}
snapEnabled={snapEnabled}
autoPlay={autoPlay}
autoPlayInterval={1500}
onProgressChange={progress}
mode="parallax"
modeConfig={{
parallaxScrollingScale: 0.9,
parallaxScrollingOffset: 50,
}}
data={colors}
renderItem={({ index }) => <SBItem index={index} />}
/>
<Pagination.Basic
progress={progress}
data={colors}
dotStyle={{ backgroundColor: "rgba(0,0,0,0.2)" }}
containerStyle={{ gap: 5, marginBottom: 10 }}
onPress={onPressPagination}
/>
<Pagination.Basic<{ color: string }>
progress={progress}
data={colors.map((color) => ({ color }))}
dotStyle={{
width: 25,
height: 4,
backgroundColor: "rgba(0,0,0,0.2)",
}}
activeDotStyle={{
overflow: "hidden",
}}
containerStyle={[
isVertical
? {
position: "absolute",
width: 25,
right: 5,
top: 40,
}
: undefined,
{
gap: 10,
marginBottom: 10,
},
]}
horizontal={!isVertical}
onPress={onPressPagination}
/>
<Pagination.Basic<{ color: string }>
progress={progress}
data={colors.map((color) => ({ color }))}
size={20}
dotStyle={{
borderRadius: 100,
backgroundColor: "rgba(0,0,0,0.2)",
}}
activeDotStyle={{
borderRadius: 100,
overflow: "hidden",
}}
containerStyle={[
isVertical
? {
position: "absolute",
width: 20,
right: 5,
top: 40,
}
: undefined,
{
gap: 5,
marginBottom: 10,
},
]}
horizontal={!isVertical}
onPress={onPressPagination}
/>
<Pagination.Basic<{ color: string }>
progress={progress}
data={colors.map((color) => ({ color }))}
size={20}
dotStyle={{
borderRadius: 100,
backgroundColor: "rgba(0,0,0,0.2)",
}}
activeDotStyle={{
borderRadius: 100,
overflow: "hidden",
}}
containerStyle={[
isVertical
? {
position: "absolute",
width: 20,
right: 5,
top: 40,
}
: undefined,
]}
horizontal={!isVertical}
renderItem={(item) => (
<View
style={{
backgroundColor: item.color,
flex: 1,
}}
/>
)}
onPress={onPressPagination}
/>
<SButton
onPress={() => setAutoPlay(!autoPlay)}
>{`${ElementsText.AUTOPLAY}:${autoPlay}`}</SButton>
<SButton
onPress={() => {
setIsVertical(!isVertical);
}}
>
{isVertical ? "Set horizontal" : "Set Vertical"}
</SButton>
<SButton
onPress={() => {
setPagingEnabled(!pagingEnabled);
}}
>
{`pagingEnabled:${pagingEnabled}`}
</SButton>
<SButton
onPress={() => {
setSnapEnabled(!snapEnabled);
}}
>
{`snapEnabled:${snapEnabled}`}
</SButton>
</View>
</GestureHandlerRootView>
);
}
export default Index;
Make sure that the GestureHandlerRootView is the top-level component or at least wraps the Carousel component in your component tree. This should resolve the error [1].
To continue talking to Dosu, mention @dosu.
This bug seems to be fixed for me in v4.0.0-canary.17.
I think it may have been fixed with v4.0.0-canary.15.
The error also went away for me in 4.0.0-alpha.12 if I wrapped both the carousel and pagination components in another GestureHandlerRootView.
The docs for react-native-gesture-handler don't seem to mention anything about nesting multiple GestureHandlerRootView components (the Carousel component includes it). But since they do recommend including it in open-source libraries this way, I assume it is probably safe to do so.
Hi, @bil-lekid. I'm Dosu, and I'm helping the react-native-reanimated-carousel team manage their backlog. I'm marking this issue as stale.
Issue Summary:
- You reported a gesture error when using pagination with the carousel, which disappears when pagination is removed.
- The error message suggested using
NativeViewGestureHandlerwithin aGestureHandlerRootView. - A solution was provided to wrap the
Carouselcomponent in aGestureHandlerRootView. - It was noted that the issue seems fixed in
v4.0.0-canary.17, and wrapping both components inGestureHandlerRootViewresolved it in4.0.0-alpha.12.
Next Steps:
- Please confirm if this issue is still relevant with the latest version of the react-native-reanimated-carousel repository. If so, you can keep the discussion open by commenting here.
- If there is no further activity, this issue will be automatically closed in 7 days.
Thank you for your understanding and contribution!