Saturday, 16 July 2022

How to do event handling for android and iOS in react native's new architecture for fabric components?

I am trying to create a Fabric component. I have got it working for the most part. The only issue I am facing is I am not able to get click listener to work for a fabric component.

I created a spec file

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<{
  value: string;
}>;

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

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

For android my fabric component looks like as follows

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

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

    private void configureViews(){
        setBackgroundColor(Color.YELLOW);
        setOnClickListener(view -> {
            onReceiveNativeEvent();
        });
    }

    public void onReceiveNativeEvent() {
        WritableMap event = Arguments.createMap();
        event.putString("message", "MyMessage");
        ReactContext reactContext = (ReactContext)getContext();
        reactContext.getJSModule(RCTModernEventEmitter.class)
                .receiveEvent(getId(),getId(),"topChange",true,0,event,1);

    }
}

Not sure what to pass targetTag, canCoalesceEvent, customCoalesceKey and category in receiveEvent

For android the app crashes and the reason being onReceiveNativeEvent() is not setup properly, if I remove onReceiveNativeEvent() it works fine without the click listener

In ViewManager I did add following code as well

public Map getExportedCustomBubblingEventTypeConstants() {
        return MapBuilder.builder().put(
                "topChange",
                MapBuilder.of(
                        "phasedRegistrationNames",
                        MapBuilder.of("bubbled", "onClickHandler")
                )
        ).build();
    }

I am following https://reactnative.dev/docs/native-components-android but it was for the old architecture and I think is not applicable for fabric components

Same for iOS https://reactnative.dev/docs/native-components-ios, the doc is not very helpful for the new architecture

For iOS, I created the header and objective-c++ file

Typically if we want to add property we do this

RCT_EXPORT_VIEW_PROPERTY(text, NSString)

Not sure how to do it for event handler

Complete source code is here https://github.com/PritishSawant/ReactNativeFabricEventListenerExample



from How to do event handling for android and iOS in react native's new architecture for fabric components?

No comments:

Post a Comment