You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中Gesture Detector无法检测手势问题求助

解决React Native BottomSheet手势检测失效问题

我是React Native新手,跟着教程从零实现BottomSheet组件,但遇到手势检测问题。以下代码中的Pan手势无法被检测到,终端无任何输出:

const gesture= Gesture.Pan().onUpdate((event)=>{
        console.log(event.translationX);
    });

相关代码及配置

CongeScreen.js

import React from 'react';
import Header from '../../components/Header';    
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { Host, Portal } from 'react-native-portalize';
import {
   SafeAreaView,
   StyleSheet,
   Text,
   useColorScheme,
   View,
   Image,
 TextInput,
 TouchableOpacity
 } from 'react-native';
 
 import {
   Colors,
   DebugInstructions,
   LearnMoreLinks,
   ReloadInstructions,
 } from 'react-native/Libraries/NewAppScreen';
import BottomSheet from '../../components/BottomSheet'
import { Modal } from 'react-native-paper';


 const CongeScreen: () => Node = ({navigation}) => {
   return (
     <SafeAreaView style={styles.body}>
          <GestureHandlerRootView style={{ flex: 1 }}>
        
        <View style={styles.container}>
          <Header
          titre={'Mes congés'}
          />

          <View style={styles.viewEmpty}>
          <Text style={styles.textEmpty}>Vous n'avez pas encore de congés</Text>
          <Image style={{marginTop:35}}
            source={require('../../assets/calendar-xmark-solid.png')} />

          </View>
          <View styles={styles.line} />
        </View> 
        <BottomSheet />  
</GestureHandlerRootView>
     </SafeAreaView>
   );
 };
 
 const styles = StyleSheet.create({
   body:{ flex:1,
   backgroundColor:'#202020',
   fontFamily:'Montserrat-Regular',
   color:'#E9E9E9',
   },   
   container:{
    paddingVertical:60, 
    paddingHorizontal:20,
    },
    viewEmpty:{
      alignItems:'center'
    },
    textEmpty:{
      color:'#484848',
      fontFamily:'Montserrat-Bold',
      fontSize:16
    }
   });
 
 export default CongeScreen;

BottomSheet.js

import React from 'react';
import { Dimensions,StyleSheet, Text, View } from "react-native";
import { Gesture, GestureDetector } from 'react-native-gesture-handler';

const { height:SCREEN_HEIGHT }= Dimensions.get('window');   
import { Host, Portal } from 'react-native-portalize';
import Animated from 'react-native-reanimated';

const BottomSheet =() =>{


    const gesture= Gesture.Pan().onUpdate((event)=>{
        console.log(event.translationX);
    })

    return (
<Portal>
        <GestureDetector gesture={gesture}>
    <Animated.View style={styles.bottomSheetContainer}>
    <View style={styles.line} />

        
            
             
    </Animated.View>
        </GestureDetector>
        </Portal>
    )
}

const styles=StyleSheet.create({
    bottomSheetContainer:{
        height: SCREEN_HEIGHT,
        width:'100%',
        backgroundColor:'white',
        position:'absolute',
        top:SCREEN_HEIGHT/1.5,
        borderRadius:25,

    },
    line:{
        
        height:3,
        width:50,
        backgroundColor:'grey',
        alignSelf:'center',
        marginVertical:10,
        borderRadius:2

        
}
});

export default BottomSheet;

依赖项

"dependencies": {
    "@gorhom/portal": "^1.0.14",
    "@react-navigation/bottom-tabs": "^6.3.2",
    "@react-navigation/native": "^6.0.11",
    "@react-navigation/native-stack": "^6.7.0",
    "@react-navigation/stack": "^6.2.2",
    "react": "18.0.0",
    "react-native": "0.69.3",
    "react-native-gesture-handler": "^2.5.0",
    "react-native-linear-gradient": "^2.6.2",
    "react-native-paper": "^4.12.4",
    "react-native-portalize": "^1.0.7",
    "react-native-reanimated": "^2.9.1",
    "react-native-safe-area-context": "^4.3.1",
    "react-native-screens": "^3.15.0",
    "react-native-svg": "^12.4.3",
    "react-native-vector-icons": "^9.2.0"
  }

babel.config.js

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [
      'react-native-reanimated/plugin',
],
};

问题排查与解决方案

1. 修正GestureHandlerRootView层级

BottomSheet通过Portal渲染,会挂载到应用根节点,而非当前页面的GestureHandlerRootView上下文。需将整个应用根组件包裹在GestureHandlerRootView内,而非仅在CongeScreen中:

// App.js 应用入口文件
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { NavigationContainer } from '@react-navigation/native';
import { Host } from 'react-native-portalize';

export default function App() {
  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      <Host>
        <NavigationContainer>
          {/* 你的导航栈或页面组件 */}
        </NavigationContainer>
      </Host>
    </GestureHandlerRootView>
  );
}

2. 调整手势监听方向与逻辑

BottomSheet为垂直拖动场景,需显式指定手势方向,并监听Y轴位移(而非X轴):

const gesture = Gesture.Pan()
  .direction(Gesture.DIRECTION_VERTICAL)
  .onUpdate((event) => {
    console.log(event.translationY); // 输出垂直方向位移
  });

3. 完善Portal配套组件

react-native-portalize的Portal必须配合根节点的Host组件使用,否则无法正确渲染到上下文,已在步骤1的App.js中添加。

4. 清除缓存重新构建

修改babel配置后,需清除缓存并重新编译项目:

npx react-native start --reset-cache
npx react-native run-android # 或 run-ios

内容的提问来源于stack exchange,提问作者mohamed yassine khabthani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 10:54:18