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
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
FlowIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With