diff --git a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts index be6b90379e..6f7166edb3 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts @@ -1,3 +1,4 @@ +import { NativeSyntheticEvent } from 'react-native' import { useRef, useMemo } from 'react' import { collectDataset } from '@mpxjs/utils' import { extendObject, useNavigation } from './utils' @@ -21,6 +22,20 @@ const globalEventState: GlobalEventState = { identifier: null } +const labelControlHandledEvents = new WeakSet() + +export const markLabelControlHandled = (evt: NativeSyntheticEvent) => { + const { nativeEvent } = evt + if (nativeEvent) { + labelControlHandledEvents.add(nativeEvent) + } +} + +export const isLabelControlHandled = (evt: NativeSyntheticEvent) => { + const { nativeEvent } = evt + return !!(nativeEvent && labelControlHandledEvents.has(nativeEvent)) +} + const baseRemovePropsMap: Record = { children: true, 'enable-background': true, diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-checkbox.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-checkbox.tsx index a2441f9222..586d04a589 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-checkbox.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-checkbox.tsx @@ -23,7 +23,7 @@ import { NativeSyntheticEvent } from 'react-native' import { warn } from '@mpxjs/utils' -import useInnerProps, { getCustomEvent } from './getInnerListeners' +import useInnerProps, { getCustomEvent, markLabelControlHandled } from './getInnerListeners' import useNodesRef, { HandlerRef } from './useNodesRef' import Icon from './mpx-icon' import { splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren, extendObject, useTextPassThrough } from './utils' @@ -123,6 +123,7 @@ const Checkbox = forwardRef, CheckboxProps>( const onTap = (evt: NativeSyntheticEvent) => { bindtap && bindtap(getCustomEvent('tap', evt, { layoutRef }, props)) + markLabelControlHandled(evt) onChange(evt) } diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-label.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-label.tsx index 45c1bbcafc..99821e5d28 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-label.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-label.tsx @@ -4,7 +4,7 @@ import { JSX, useRef, forwardRef, ReactNode, useCallback, createElement } from 'react' import { View, ViewStyle, NativeSyntheticEvent } from 'react-native' import { noop, warn } from '@mpxjs/utils' -import useInnerProps, { getCustomEvent } from './getInnerListeners' +import useInnerProps, { getCustomEvent, isLabelControlHandled } from './getInnerListeners' import useNodesRef, { HandlerRef } from './useNodesRef' import { splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren, extendObject, useTextPassThrough } from './utils' import { LabelContext, LabelContextValue } from './context' @@ -72,7 +72,9 @@ const Label = forwardRef, LabelProps>( const onTap = useCallback((evt: NativeSyntheticEvent) => { const { bindtap } = propsRef.current bindtap && bindtap(getCustomEvent('tap', evt, { layoutRef }, { props: propsRef.current })) - contextRef.current.triggerChange(evt) + if (!isLabelControlHandled(evt)) { + contextRef.current.triggerChange(evt) + } }, []) const innerProps = useInnerProps( diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-radio.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-radio.tsx index ec27a68e04..408b2c449a 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-radio.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-radio.tsx @@ -8,7 +8,7 @@ import { JSX, useRef, useState, forwardRef, useEffect, ReactNode, useContext, Di import { View, StyleSheet, ViewStyle, NativeSyntheticEvent } from 'react-native' import { warn } from '@mpxjs/utils' import { LabelContext, RadioGroupContext } from './context' -import useInnerProps, { getCustomEvent } from './getInnerListeners' +import useInnerProps, { getCustomEvent, markLabelControlHandled } from './getInnerListeners' import useNodesRef, { HandlerRef } from './useNodesRef' import { splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren, extendObject, useTextPassThrough } from './utils' import Icon from './mpx-icon' @@ -112,6 +112,7 @@ const Radio = forwardRef, RadioProps>( const onTap = (evt: NativeSyntheticEvent) => { bindtap && bindtap(getCustomEvent('tap', evt, { layoutRef }, props)) + markLabelControlHandled(evt) onChange(evt) }