
移动开发UI组件【免费下载链接】react-native-gesture-handlerDeclarative API exposing platform native touch and gesture system to React Native.项目地址https://gitcode.com/gh_mirrors/re/react-native-gesture-handler点击查看免费下载本指南以 react-native-gesture-handler 仓库中的skills/gesture-handler-3-migration/SKILL.md为骨架系统讲解将使用 Gesture Handler 2RNGH2Builder API 的组件升级到 Gesture Handler 3RNGH3Hook API 的完整路径手势构造、回调改名、关系组合、StateManager 命令式状态管理、与 Reanimated 的集成、SVG 场景下的新检测器以及 Legacy 组件与Touchable的统一替换。读完你将掌握一套可逐文件执行的迁移清单并理解每个改动背后的源码级原理。迁移总览三步走与八条指令本技能的核心职责是扫描使用了 Gesture Handler Builder API 的 React Native 组件将其更新为新的 Hook API并同步更新相关类型与组件以适配新版本。适用场景非常明确更新从react-native-gesture-handler导入的组件用法升级到 Gesture Handler 3迁移到新的基于 Hook 的手势 API。迁移过程遵循以下 8 条核心指令SKILL.md 的 Instructions 部分识别所有来自react-native-gesture-handler的 import将每个Gesture.X()调用替换为对应的useXGesture()Hook将Gestureimport 替换为所用 Hook 的 import将 Builder 方法链转换为配置对象更新回调名称onStart→onActivate等用关系 Hook 替换组合手势同时牢记 Hook 调用规则Rules of Hooks若涉及 SVG将GestureDetector更新为InterceptingGestureDetector/VirtualGestureDetector根据下文 Legacy components 章节更新从react-native-gesture-handler导入的组件用法。本质上这是一次API 形态的整体转换Builder API 用方法链描述手势Gesture.Pan().onStart(...).simultaneousWithExternalGesture(...)而 Hook API 用一个普通配置对象描述一切usePanGesture({ onBegin: ..., simultaneousWith: ... })。下面按主题逐个展开。迁移手势从Gesture.X()到useXGesture(config)所有 Builder 手势在 Hook API 中都有对应物Gesture.X()变成useXGesture(config)。原来 Builder 上的方法现在变成同名的配置对象字段除非下文另有说明。对应关系覆盖 Tap、Pan、Pinch、Rotation、LongPress、Fling、Hover、Manual、Native 九类手势它们的 Hook 与事件类型导出均可在 src/v3/hooks/gestures/index.ts 中逐一确认。唯一的例外是Gesture.ForceTouchHook API 中没有对应物迁移时需另行处理该场景。以useTapGesture为例useTapGesture.ts 展示了 Hook 内部如何把用户配置重映射到原生侧maxDistance→maxDist、maxDuration→maxDurationMs、maxDelay→maxDelayMs见TapPropsMapping。也就是说配置对象的字段名以 Hook 层为准Hook 内部会自动转换后再传给原生模块开发者无需关心原生参数名。从源码注释与类型定义TapTypes.ts、PanTypes.ts可以整理出常用配置的默认值供迁移时对照useTapGestureminPointers默认 1numberOfTaps默认 1maxDuration默认 500msmaxDelay默认 500msmaxDistance/maxDeltaX/maxDeltaY单位为点迁移后shouldCancelWhenOutside默认会被设置为true见transformTapProps。usePanGestureminDistance、minVelocity、minVelocityX、minVelocityY点/秒minPointers/maxPointersactiveOffsetX/Y与failOffsetX/Y支持number | [number, number]区间形式单个数值pp 0时表示(-inf, p)否则表示(-p, inf)enableTrackpadTwoFingerGesture用于 iPad 触控板双指手势averageTouches仅 Android 生效。一个典型的迁移对照// RNGH2Builder 方法链 const gesture Gesture.Pan() .minDistance(10) .onStart((e) { ... }) .onUpdate((e) { ... }) .onEnd((e, success) { ... }); // RNGH3配置对象 const gesture usePanGesture({ minDistance: 10, onBegin: (e) { ... }, onUpdate: (e) { ... }, onDeactivate: (e) { ... }, });回调改名与事件类型统一RNGH3 重命名了部分回调这是迁移中最容易被忽略、也最容易导致逻辑错误的部分RNGH2 旧回调RNGH3 新回调onStartonActivateonEndonDeactivateonTouchesCancelledonTouchesCancel三个配套要点onDeactivate/onFinalize不再接收第二个didSucceed/success布尔参数。取而代之的是事件对象上的canceled属性且逻辑是反转的——canceled: true对应旧 API 的success: false// 旧 (RNGH2) .onEnd((event, success) { if (success) { /* gesture succeeded */ } }) // 新 (RNGH3) onDeactivate: (event) { if (!event.canceled) { /* gesture succeeded */ } }Hook API 中onChange已移除。原本在onChange里读取的*change*属性如 Pan 的changeX/changeY、translationX/Y、velocityX/Y现在直接放在onUpdate收到的事件对象中。PanExtendedHandlerData类型PanTypes.ts明确列出了这些字段。同一手势的所有回调现在共用同一种事件类型Hook事件类型usePanGesture()PanGestureEventuseTapGesture()TapGestureEventuseLongPressGesture()LongPressGestureEventuseRotationGesture()RotationGestureEventusePinchGesture()PinchGestureEventuseFlingGesture()FlingGestureEventuseHoverGesture()HoverGestureEventuseNativeGesture()RotationGestureEventuseManualGesture()ManualGestureEventuseNativeGesture在 SKILL.md 中标注的事件类型为RotationGestureEvent迁移时按此对照即可。唯一例外是触摸事件onTouchesDown、onTouchesUp、onTouchesMove、onTouchesCancel无论使用哪个 Hook它们都接收GestureTouchEvent。StateManager从回调参数到全局GestureStateManagerRNGH2 中stateManager作为参数传给TouchEvent回调RNGH3 中不再传递改用全局的GestureStateManager。其命令式状态管理方法src/v3/gestureStateManager.ts 中可以直接看到实现activate(handlerTag)—— 内部调用_setGestureStateSync(handlerTag, State.ACTIVE)deactivate(handlerTag)—— 对应旧 API 的.end()内部置为State.ENDfail(handlerTag)—— 内部置为State.FAILED。handlerTag有两种获取方式从 Hook 返回的手势对象上取gesture.handlerTag从事件对象上取event.handlerTag。一个关键约束回调定义中不能引用正在定义的那个手势对象本身会造成循环引用。此时应通过事件获取handlerTag例如在onTouchesUp里用event.handlerTag调用GestureStateManager.activate(...)。另外注意必须移除GestureStateManager.begin()调用——RNGH3 中手势必须先通过触摸事件自动进入 BEGAN 状态之后才能由GestureStateManager激活不再支持手动 begin。迁移关系组合手势与跨组件交互组合手势Builder API 的组合方法在 Hook API 中对应关系 HookGesture.Race()→useCompetingGestures()Gesture.Simultaneous()→useSimultaneousGestures()Gesture.Exclusive()→useExclusiveGestures()例如Gesture.Simultaneous(gesture1, gesture2)变成useSimultaneousGestures(pan1, pan2)。这些 Hook 的实现位于 src/v3/hooks/composition/以useSimultaneousGestures为例useSimultaneousGestures.ts它内部调用useComposedGesture(ComposedGestureName.Simultaneous, ...gestures)生成一个组合手势对象组合对象通过gesture.handlerTags复数暴露内部各子手势的 tag——这一点在InterceptingGestureDetector/VirtualGestureDetector中都有对应的isComposedGesture分支处理。由于关系 Hook 本质是 Hook必须遵守 Rules of Hooks不要在条件、循环或嵌套函数中调用组合时注意各子手势 Hook 的调用顺序与依赖数组。跨组件关系属性用于定义跨组件交互的属性也统一改名Builder 链式方法 → 配置对象字段.simultaneousWithExternalGesture→simultaneousWith:.requireExternalGestureToFail→requireToFail:.blocksExternalGesture→block:在useGesture内部useGesture.ts这三个字段会被prepareRelations收集并挂到手势对象的gestureRelations上再通过检测器同步到原生侧保证跨组件的竞争/同步/阻塞关系正确生效。GestureDetector用法与红线GestureDetector是react-native-gesture-handler的关键组件新实现导出于 src/v3/detectors/GestureDetector.tsx。它同时支持用 Hook API 或 Builder 模式创建的手势但两者不能混用——要么全部用 Hook 手势要么全部用 Builder 手势。另一条红线不要把同一个手势实例复用到多个 GestureDetector 上会导致未定义行为undefined behavior。若同一逻辑需要在多处生效应为每处单独调用 Hook 生成独立实例。与 Reanimated 的集成自动 worklet 化Hook API 与 Reanimated 的集成是默认开启的只要安装了 Reanimated。Worklets 的 Babel 插件会自动把在手势配置对象中内联定义的回调标记为 worklet因此不需要在函数开头手动加worklet;指令。但有两种情况不会被自动 worklet 化需要手动补worklet;指令回调在配置对象之外定义const callback () { console.log(_WORKLET); }; const gesture useTapGesture({ onBegin: callback, // 不会自动 worklet 化 });回调被任何高阶函数包裹const gesture useTapGesture({ onBegin: useCallback(() { console.log(_WORKLET); }, []), // 不会自动 worklet 化 });源码层面configUtils.ts 中的resolveInternalConfigProps会根据是否存在 worklet 事件处理器hasWorkletEventHandlers以及disableReanimated等标志计算shouldUseReanimatedDetector从而决定使用 Reanimated 原生检测器还是普通检测器——这解释了为什么回调是否在配置对象内联会直接影响运行时行为。禁用 Reanimated 与 runOnJSHook API 创建的手势默认启用 Reanimated 集成若已安装即所有回调在 UI 线程执行。若需动态控制线程runOnJS: true—— 回调在 JS 线程执行runOnJS: false—— 回调在 UI 线程执行默认值为false。在useGestureuseGesture.ts中还有一条约束disableReanimated在手势创建后不得再改变否则会抛出错误测试环境isTestEnv()下若未显式设置disableReanimated会被强制置为true见 configUtils.ts。依赖视图层级组件的迁移InterceptingGestureDetector 与 VirtualGestureDetector部分组件如SVG依赖视图层级view hierarchy才能正常工作。RNGH3 中普通GestureDetector会打乱这种层级为此引入了两个新检测器导出于 src/v3/detectors/index.tsInterceptingGestureDetector功能与GestureDetector类似但还能作为其组件子树内VirtualGestureDetector的代理proxy。由于它可以仅用于为虚拟检测器建立上下文因此gesture属性是可选的。实现见 InterceptingGestureDetector.tsx它维护InterceptingDetectorContext子级虚拟检测器通过该 context 注册自己register/unregister父级再把所有子级的事件处理器组合转发createGestureEventHandler会遍历virtualChildren逐一调用。VirtualGestureDetector行为类似 RNGH2 的GestureDetector但不是宿主组件host component因此不会干扰宿主视图层级可以在不破坏依赖层级的组件如 SVG的前提下挂载手势。实现见 VirtualDetector.tsx它通过findNodeHandle拿到目标视图的 tag 后向InterceptingGestureDetector注册为virtualChild最终由父级代理到原生检测器。警告VirtualGestureDetector必须是InterceptingGestureDetector的后代。这一点在源码中是强制的VirtualDetector调用useRequiredInterceptingDetectorContext()若 context 不存在会直接抛出错误VirtualGestureDetector must be a descendant of an InterceptingGestureDetector见 VirtualDetector.tsx。迁移 SVGRNGH2 可以直接在SVG上使用GestureDetectorRNGH3 中与 SVG 交互的正确方式改为使用InterceptingGestureDetector包裹、内部用VirtualGestureDetector挂载手势import Svg, { Path } from react-native-svg; import { InterceptingGestureDetector, VirtualGestureDetector, usePanGesture, } from react-native-gesture-handler; const MySvgWithGestures () { const pan usePanGesture({ onUpdate: (e) { /* ... */ } }); return ( InterceptingGestureDetector Svg VirtualGestureDetector gesture{pan} Path d... / /VirtualGestureDetector /Svg /InterceptingGestureDetector ); };Legacy 组件升级受阻时的过渡方案当组件的使用依赖 RNGH3 组件上已不可用的 API如waitFor、simultaneousWith、blocksHandler、onHandlerStateChange、onGestureEvent等 props时无法在孤立文件内轻松完成迁移。此时的处理策略将 import 更新为该组件的 Legacy 版本并告知用户其依赖需要先迁移若迁移可行且用户未事先说明意图应使用提问工具澄清组件应该使用新实现import 无Legacy前缀还是回退到旧实现import 带Legacy前缀。相关规则与现状可在 src/index.ts 的导出中逐一印证不要把 Gesture Handler 的按钮替换成 React Native 自带组件反之亦然——迁移时保持两者都在react-native-gesture-handler内部。按钮实现已整体更新解决了大部分历史按钮问题并内部用新 Hook API 重写旧 JS 实现仍可用但加了Legacy前缀RectButton现在可用为LegacyRectButtonBaseButton→LegacyBaseButton、BorderlessButton→LegacyBorderlessButton、RawButton→LegacyRawButton。这些 Legacy 按钮底层仍使用新的原生组件。PureNativeButton已被移除。若遇到需告知用户并让其决定处理方式可用其他按钮实现相近功能。ReanimatedSwipeable的dragOffsetFromRightprop现在接受负值若原来使用正值迁移时必须改符号。源码中ReanimatedSwipeable的默认值即为负数dragOffsetFromRight -DEFAULT_DRAG_OFFSET见 ReanimatedSwipeable.tsx且内部对正值做了dragOffsetFromRight should be non-positive.的校验。其他组件也已内部用新 Hook API 重写但仍以原名导出通常无需改动需要旧实现时可使用Legacy前缀版本例如ScrollView→LegacyScrollView同类还有LegacyFlatList、LegacyRefreshControl、LegacySwitch、LegacyTextInput、LegacyDrawerLayoutAndroid等见 src/index.ts。所有createNativeWrapper的使用含 import 语句与函数调用都要重命名为legacy_createNativeWrapper。统一迁移到TouchableRNGH3 中Touchable组件同时取代了旧按钮BaseButton、RectButton、BorderlessButton与旧核心风格 TouchablesTouchableOpacity、TouchableHighlight、TouchableWithoutFeedback、TouchableNativeFeedback。它是个单一组件视觉反馈完全由 props 控制——迁移的目标是选对 props 组合而不是换用不同组件。Touchable导出与类型定义见 src/v3/components/Touchable/Touchable.tsx 与 TouchableProps.ts。迁移时用到的 props 一览含默认值均可在TouchableProps.ts中核实onPress(event)—— 成功点击时触发。注意签名变化旧BaseButton.onPress接收(pointerInside: boolean)新Touchable.onPress接收手势事件对象ButtonEvent。onPressIn(event)/onPressOut(event)—— 指针首次按下 / 释放或离开时触发。onLongPress()—— 按住达到delayLongPress毫秒后触发默认600长按触发后随后的释放不再调用onPress。disabled—— 取代旧enabledprop注意语义相反默认false。cancelOnLeave—— 指针离开组件边界时是否取消按压默认true用于替换原生按钮的shouldCancelWhenOutsideWeb 上该 prop 无效行为等同true。activeOpacity—— 按压时作用于组件本身的透明度对应TouchableOpacity默认1不变透明。underlayColoractiveUnderlayOpacity—— 按压时下衬层的颜色与透明度对应TouchableHighlight/RectButtonunderlayColor默认transparentactiveUnderlayOpacity默认0.105。androidRipple—— Android 水波纹配置{ color?, radius?, borderless?, foreground? }不设置则不渲染原生水波纹用于替换TouchableNativeFeedback。animationDuration—— 按压/悬停动画时长毫秒。传单个数字应用于所有阶段或传对象{ in, out }可再带tap/hover/longPress覆盖项默认50in /100out。hitSlop、testID、style、children—— 与之前一致。替换 Gesture Handler 按钮旧组件替换为iOS / 跨平台默认BaseButtonTouchable /默认 propsRectButtonTouchable underlayColorblack animationDuration{0} /BorderlessButtonTouchable activeOpacity{0.3} animationDuration{0} /Android 水波纹注意点旧RectButton/BorderlessButton在 Android 上使用原生主题水波纹而Touchable在未设置androidRipple时不渲染水波纹。为保留旧 Android 视觉反馈应在 Android 上设置androidRipple以替代underlayColor/activeOpacity/animationDuration不要同时组合——Android 上的视觉反馈就是水波纹RectButton→androidRipple{{}}BorderlessButton→androidRipple{{ borderless: true }}匹配旧的无边界水波纹形状推荐用Platform.select按平台施加不同 propsRectButton的完整示例import { Platform } from react-native; Touchable {...Platform.select({ android: { androidRipple: {} }, default: { underlayColor: black, animationDuration: 0 }, })} /替换旧版核心 Touchables旧组件替换为TouchableOpacityTouchable activeOpacity{0.2} animationDuration{{ in: 0, out: 150 }} /TouchableHighlightTouchable underlayColor{...} activeUnderlayOpacity{1} activeOpacity{...} /—— 最接近的近似非 1:1见下方说明TouchableWithoutFeedbackTouchable /无视觉反馈 propsTouchableNativeFeedbackTouchable androidRipple{{ foreground: true }} /关于TouchableNativeFeedbackandroidRipple必须显式设置否则不渲染水波纹。旧组件默认useForeground: true因此{ foreground: true }是最接近的默认替换仅当原代码传了useForeground{false}时才去掉foreground。若原代码自定义了backgroundprop 的color/radius/borderless请对应补上。关于TouchableHighlight不可能做到 1:1 替换。旧组件中容器自身的背景就是下衬实心underlayColoractiveOpacity只让上层子内容变暗下衬会透出变暗的子内容Touchable则在背景与子内容之间有独立的下衬层其activeOpacity会同时作用于整个组件背景 下衬 子内容。最接近的近似原样保留underlayColor与activeOpacity再加activeUnderlayOpacity{1}让下衬层以实心渲染并告知用户由于层级不同视觉反馈可能与旧组件存在差异。最后重申迁移过程中不要将 Gesture Handler 的按钮 / Touchables 与 React Native 核心组件互换两者都保持在react-native-gesture-handler内。被替换的类型Legacy 前缀Builder API 使用的大部分类型如TapGesture在 RNGH3 中仍然存在但改由新的 Hook API 使用。Builder API 对应的旧类型现在带Legacy前缀例如TapGesture→LegacyTapGesture。在 src/index.ts 中可以确认完整映射LegacyPanGesture、LegacyPinchGesture、LegacyRotationGesture、LegacyLongPressGesture、LegacyFlingGesture、LegacyHoverGesture、LegacyManualGesture、LegacyForceTouchGesture以及组合类型LegacyComposedGesture、LegacyExclusiveGesture、LegacyRaceGesture、LegacySimultaneousGesture和LegacyGestureStateManager。迁移时若旧代码显式引用了这些类型需同步加前缀。迁移自检清单完成一个文件后建议按 SKILL.md 的指令顺序逐项核对import 是否全部来自react-native-gesture-handler且已收敛为实际用到的 Hook / 组件所有Gesture.X()是否已改为useXGesture(config)方法链是否已拍平为配置对象回调是否已改名onStart→onActivate、onEnd→onDeactivate、onTouchesCancelled→onTouchesCancelsuccess判断是否已改为event.canceled的反转逻辑onChange中的*change*字段是否已移到onUpdate事件上组合手势是否已换成useSimultaneousGestures/useCompetingGestures/useExclusiveGestures且遵守 Rules of Hooks跨组件关系属性是否已改为simultaneousWith/requireToFail/blockSVG 场景是否已改用InterceptingGestureDetector 其子树内的VirtualGestureDetector依赖旧 propswaitFor、onHandlerStateChange等的组件是否已按 Legacy components 章节处理需要确认意图时是否已向用户澄清Touchable迁移是否按替换表选择了正确的 props 组合Android 上是否用androidRipple替代了视觉反馈 props旧类型引用是否已加Legacy前缀createNativeWrapper是否已改为legacy_createNativeWrapper。按此清单推进即可在保持行为一致的前提下把组件库完整、可验证地从 Gesture Handler 2 升级到 Gesture Handler 3。赞分享移动开发UI组件【免费下载链接】react-native-gesture-handlerDeclarative API exposing platform native touch and gesture system to React Native.项目地址https://gitcode.com/gh_mirrors/re/react-native-gesture-handler点击查看免费下载相关推荐NanoClaw Emacs 频道完整卸载指南从适配器、凭据到配置的干净移除NanoClaw Emacs 频道完整卸载指南从适配器、凭据到配置的干净移除 导读 NanoClaw 通过「频道技能」skill把 Emacs 变成 AI移动开发UI组件react-native-gesture-handler 的 Gesture 对象手势创建、组合与 v3 Hook API 迁移指南react native gesture handler 的 Gesture 对象手势创建、组合与 v3 Hook API 迁移指南 Gesture 是 re移动开发UI组件React Native Gesture Handler终极版本兼容指南从0.59到0.82平滑升级全攻略React Native Gesture Handler终极版本兼容指南从0.59到0.82平滑升级全攻略 React Native Gesture Hand移动开发UI组件上一篇如何在Mac上制作Windows启动盘WinDiskWriter终极解决方案下一篇Obsidian文件搜索新方式Claudian插件的智能搜索功能创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考