简体   繁体   中英

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?: BubblingEventHandler<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(),"onClickHandler",true,0,event,1);

    }
}

Not sure what to pass first param as int , canCoalesceEvent , customCoalesceKey and category in receiveEvent

In ViewManager I did add following code as well

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

For android I am not getting the callback from native android to js side

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

iOS

Assuming native spec you posted is correct (I'm not really familiar with TypeScript + Codegen duo) when you run pod install command in your ios/ directory codegen should generate EventEmitters cpp file (+ header) in React-Codegen pod (you can see below how to find it in XCode)

link to the screenshot with Pods structure

You can then use these classes in your Objective-C++ code to emit the events:

if (_eventEmitter != nullptr) {
    std::dynamic_pointer_cast<const facebook::react::$$NAME OF YOUR EVENT EMITTER TYPE$$>(_eventEmitter)
        ->onEvent(facebook::react::$$NAME OF YOUR EVENT EMITTER TYPE::OnEvent{.value = $$VALUE$$});
}

See links below to see how it is done in react-native-screens

  1. Native component spec in Flow
  2. Event emission in Obj-C++ code
  3. Event exposure in screen manager - I'm not quite sure if this line is necessary, haven't tested it out yet.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM