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
.