react-native icon indicating copy to clipboard operation
react-native copied to clipboard

RCTModernEventEmitter fires twice for android fabric component

Open BraveEvidence opened this issue 3 years ago • 5 comments

Description

I am trying to create a fabric component for android, specifically I want to use the onClickHandler of the button component and pass a callback to react-native side via RCTModernEventEmitter. It works fine for iOS but for android the RCTModernEventEmitter emits twice every time I click the button

This is my spec

import type {HostComponent, ViewProps} from 'react-native';
import type {
  DirectEventHandler
} from 'react-native/Libraries/Types/CodegenTypes';
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';

type Event = Readonly<{
  text?: string;
}>;

interface NativeProps extends ViewProps {
  text: string;
  onClickHandler?: DirectEventHandler<Event>; ////Event name should start with on
}

export default codegenNativeComponent<NativeProps>(
  'MyButtonView',
) as HostComponent<NativeProps>;

On native side I have created following files

public class MyButtonViewManager extends SimpleViewManager<MyButtonView> {

    public static final String NAME = "MyButtonView";
    ReactApplicationContext mCallerContext;

    public MyButtonViewManager(ReactApplicationContext reactContext) {
        mCallerContext = reactContext;
    }
 
    @NonNull
    @Override
    public String getName() {
        return NAME;
    }

    @NonNull
    @Override
    protected MyButtonView createViewInstance(@NonNull ThemedReactContext reactContext) {
        return new MyButtonView(reactContext);
    }

    @ReactProp(name = "text")
    public void setQrCodeText(MyButtonView view, String text) {
        view.setText(text);
    }


    @Nullable
    @Override
    public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
        return MapBuilder.of("topOnClickHandler",
                MapBuilder.of("registrationName", "onClickHandler")
        );
    }

}

public class MyButtonClickEvent extends Event<MyButtonClickEvent> {

    public MyButtonClickEvent(int viewId) {
        super(viewId);
    }
 
    @Override
    public String getEventName() {
        return "topOnClickHandler";
    }

    @Override
    public void dispatchModern(RCTModernEventEmitter rctEventEmitter) {
        super.dispatchModern(rctEventEmitter);
        rctEventEmitter.receiveEvent(-1,
                getViewTag(),getEventName(),
                Arguments.createMap()
        );
    }

    @Nullable
    @Override
    protected WritableMap getEventData() {
        WritableMap event = Arguments.createMap();
        event.putString("message", "MyMessage");
        return event;
    }
}

public class MyButtonView extends androidx.appcompat.widget.AppCompatButton {

    public MyButtonView(Context context) {
        super(context);
        configureViews();
    }

    private void configureViews(){
        setBackgroundColor(Color.YELLOW);
        setOnClickListener(view -> {
            ReactContext reactContext = (ReactContext)getContext();
            EventDispatcher eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(
                    reactContext ,getId()
            );
            eventDispatcher.dispatchEvent(new MyButtonClickEvent(getId()));
        });
    }
}

On JS side

<MyButtonView
          style={{height: 100, width: 100, margin: 20}}
          onClickHandler={(value: any) => {
            console.log('Hello ok bye', value.nativeEvent);
          }}
          text="Hello"
        />

I get value in onClickHandler of MyButtonView twice even though I press the button once

Fullrepo is here https://github.com/PritishSawant/ReactNativeFabricEventListenerExample

Version

0.69.1

Output of npx react-native info

info Fetching system and libraries information... System: OS: macOS 12.4 CPU: (8) x64 Apple M1 Memory: 44.15 MB / 8.00 GB Shell: 5.8.1 - /bin/zsh Binaries: Node: 16.13.0 - /usr/local/bin/node Yarn: 1.22.10 - /usr/local/bin/yarn npm: 8.1.0 - /usr/local/bin/npm Watchman: 2022.03.21.00 - /opt/homebrew/bin/watchman Managers: CocoaPods: 1.11.3 - /opt/homebrew/bin/pod SDKs: iOS SDK: Platforms: DriverKit 21.4, iOS 15.5, macOS 12.3, tvOS 15.4, watchOS 8.5 Android SDK: Not Found IDEs: Android Studio: 2021.2 AI-212.5712.43.2112.8609683 Xcode: 13.4.1/13F100 - /usr/bin/xcodebuild Languages: Java: javac 16 - /usr/bin/javac npmPackages: @react-native-community/cli: Not Found react: 18.0.0 => 18.0.0 react-native: 0.69.0 => 0.69.0 react-native-macos: Not Found npmGlobalPackages: react-native: Not Found

Steps to reproduce

Clone https://github.com/PritishSawant/ReactNativeFabricEventListenerExample

Run yarn in terminal

Run yarn android

Snack, code example, screenshot, or link to a repository

https://github.com/PritishSawant/ReactNativeFabricEventListenerExample

BraveEvidence avatar Jul 28 '22 03:07 BraveEvidence

This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] avatar Jan 25 '23 02:01 github-actions[bot]

This issue still exist in version 0.71.1. Please check sample repo for a reproducible

BraveEvidence avatar Jan 27 '23 01:01 BraveEvidence

Removing super.dispatchModern(rctEventEmitter) resolves the issue

BraveEvidence avatar Feb 01 '23 13:02 BraveEvidence

The above thing does not resolve the issue

BraveEvidence avatar Feb 26 '23 13:02 BraveEvidence

This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] avatar Feb 05 '24 05:02 github-actions[bot]

@BraveEvidence is this still an issue? Can we update the repro to 0.73 and try again?

cortinico avatar Feb 09 '24 18:02 cortinico

This issue is waiting for author's feedback since 24 days. Please provide the requested feedback or this will be closed in 7 days.

github-actions[bot] avatar Mar 05 '24 05:03 github-actions[bot]

Closing as @BraveEvidence is unreponsive and I'm not able to reproduce

cortinico avatar Mar 05 '24 15:03 cortinico