React Native中PanGestureHandler失效:BottomSheet无法拖拽问题
BottomSheet实现问题与TypeScript错误解决
问题背景
我尝试实现一个可通过按钮点击上下滑动、但不支持拖拽的BottomSheet,编写了如下代码,但TypeScript对<PanGestureHandler>标签标红报错。
原代码
import { PanGestureHandler, PanGestureHandlerGestureEvent } from 'react-native-gesture-handler'; import React from 'react'; import {Sheet} from './styles'; import { useAnimatedGestureHandler, useSharedValue } from 'react-native-reanimated'; import { useWindowDimensions } from 'react-native'; export const SheetContainer = (props: any) => { const {style, } = props; const children = React.Children.map(props.children, c => React.cloneElement(c, { slideCallback: '', }), ); const { height: deviceHeight, width: deviceWidth } = useWindowDimensions(); const top = useSharedValue(deviceHeight); const gestureHandler = useAnimatedGestureHandler<any>({ onStart(_, context: any) { context.startTop = top.value; }, onActive(event, context: any) { top.value = context.startTop + event.translationY; }, onEnd() { if (top.value > deviceHeight / 4) { top.value = deviceHeight; } else { top.value = deviceHeight - 190; } }, }) return ( <PanGestureHandler onGestureEvent={gestureHandler}> <Sheet {...props} style={style}>{children}</Sheet> </PanGestureHandler> ); };
TypeScript错误提示
(alias) const PanGestureHandler: React.ComponentType<PanGestureHandlerProps & React.RefAttributes>
import PanGestureHandler
Type '{ children: Element; onGestureEvent: OnGestureEvent; }' is not assignable to type 'IntrinsicAttributes & PanGestureHandlerProps & RefAttributes'.
Property 'children' does not exist on type 'IntrinsicAttributes & PanGestureHandlerProps & RefAttributes'.
解决方法
1. 核心问题分析
- TypeScript报错的原因:
PanGestureHandler本身不支持直接传入children属性,它需要配合动画组件使用,但更关键的是——你的需求是按钮点击控制滑动,完全不需要PanGestureHandler(这个组件是用来处理拖拽手势的),属于冗余代码。
2. 修改后的代码
移除多余的手势处理逻辑,实现按钮控制的滑动功能:
import React from 'react'; import { Sheet } from './styles'; import { useSharedValue, withSpring } from 'react-native-reanimated'; import { useWindowDimensions } from 'react-native'; export const SheetContainer = (props: any) => { const { style } = props; const { height: deviceHeight } = useWindowDimensions(); // 控制BottomSheet位置的共享值,初始在屏幕底部 const top = useSharedValue(deviceHeight); // 给子组件提供的滑动控制回调,点击时切换展开/收起状态 const slideCallback = () => { top.value = withSpring( top.value === deviceHeight ? deviceHeight - 190 : deviceHeight ); }; const children = React.Children.map(props.children, c => React.cloneElement(c, { slideCallback, // 传递实际可用的回调函数 }), ); // 将top动画值绑定到Sheet的样式上 return <Sheet {...props} style={[style, { top }]}>{children}</Sheet>; };
3. 补充说明
Sheet组件的样式需要设置position: 'absolute',确保它能基于屏幕底部上下滑动- 使用
withSpring添加弹簧动画,让BottomSheet的展开/收起过渡更自然 - 在子组件中调用
props.slideCallback()即可触发滑动操作
内容的提问来源于stack exchange,提问作者yaxx
相关产品推荐
相关产品推荐

