Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the alternatives to RCTEventEmitter and RCTModernEventEmitter?

I am trying to integrate a Native UI component in react-native using the new architecture with fabric enabled

Here is my spec file

import type {HostComponent, ViewProps} from 'react-native';
import type {
  DirectEventHandler,
  BubblingEventHandler,
} 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>;

Then on native side I 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 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()));
        });
    }
}

public class MyButtonClickEvent extends Event<MyButtonClickEvent> {

    public MyButtonClickEvent(int viewId) {
        super(viewId);
    }

    @Override
    public String getEventName() {
        return "topOnClickHandler";
    }

    @Override
    public void dispatch(RCTEventEmitter rctEventEmitter) {
        super.dispatch(rctEventEmitter);
        rctEventEmitter.receiveEvent(getViewTag(), getEventName(), Arguments.createMap());
    }

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

What is the alternative to dispatch and RCTEventEmitter as both are deprecated? I was looking into RCTModernEventEmitter and it also extends the deprecated RCTEventEmitter

Also i have to change the event name from OnClickHandler to topOnClickHandler in Native Android side. It was throwing hermes error. Not sure why there should be top prefix, why can't it just be OnClickHandler.

like image 605
Pritish Avatar asked Oct 24 '25 15:10

Pritish


1 Answers

From the react-native source code:

This [RCTModernEventEmitter] is a transitional replacement for RCTEventEmitter that works with Fabric and non-Fabric renderers. RCTEventEmitter works with Fabric as well, but there are negative perf implications and it should be avoided.

You can use this for now as a replacement that works with Fabric.

This [RCTModernEventEmitter] interface will also be deleted in the distant future and be replaced with a new interface that doesn't need the old receiveEvent method at all. But for the foreseeable future, this is the recommended interface to use for EventEmitters.

However, in the long run this will be removed.

There's ReactEventEmitter that might help based on your use-case.

like image 54
Ekaansh Arora Avatar answered Oct 26 '25 04:10

Ekaansh Arora



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!