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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 12:40:38