question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Codegen for TurboModules does not allow for Events to be Emitted

See original GitHub issue

Description

I am working on an app that requires a native module to be able to emit random events. In my case I am building a pedometer and steps can come from the native part of the application at random times. I can’t use simple method calls because of this behaviour. I also want to use a BLE heart rate monitor which again requires the ability to use random events because the sensor data comes in at random times.

I tried to use DirectEventHandler in my Codegen file and the codegen compiler just shows errors. My interface code looks like this:

import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';
import type {
  DirectEventHandler,
  Int32,
} from 'react-native/Libraries/Types/CodegenTypes';

export interface Spec extends TurboModule {
  multiply(a: number, b: number): number;
  add(a: number, b: number): number;
  randomEvent: DirectEventHandler<{ data: Int32 }>;
}

export default TurboModuleRegistry.getEnforcing<Spec>('RtmPedometer');

If I comment out the randomEvent code then Codegen works perfectly fine and I have no issues. This seems to be the only type in the documentation we have for event emitting unless I am missing something. This issue is especially frustrating because this was easy to do with the old arch and is really well documented. See: https://reactnative.dev/docs/native-modules-android#sending-events-to-javascript . This bug with DirectEventHandler is integral to how TurboModules should work and I feel like it should be a pretty high priority fix.

Version

0.70.5

Output of npx react-native info

System:
    OS: macOS 12.5
    CPU: (10) arm64 Apple M1 Pro
    Memory: 149.16 MB / 16.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 16.17.0 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 8.15.0 - /usr/local/bin/npm
    Watchman: Not Found
  Managers:
    CocoaPods: 1.11.3 - /Users/danielfriyia/.rvm/gems/ruby-3.0.0/bin/pod
  SDKs:
    iOS SDK:
      Platforms: DriverKit 21.4, iOS 16.0, macOS 12.3, tvOS 16.0, watchOS 9.0
    Android SDK: Not Found
  IDEs:
    Android Studio: 2021.2 AI-212.5712.43.2112.8815526
    Xcode: 14.0/14A309 - /usr/bin/xcodebuild
  Languages:
    Java: 11.0.16 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: 18.1.0 => 18.1.0 
    react-native: 0.70.5 => 0.70.5 
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Steps to reproduce

Clone the Reproducer Repo: https://github.com/friyiajr/EventBugReproducer

Run the command yarn bootstrap

At this point you will see it fail. If you want it to succeed comment out the randomEvent line along with its import statements.

Snack, code example, screenshot, or link to a repository

https://github.com/friyiajr/EventBugReproducer

Issue Analytics

  • State:closed
  • Created 10 months ago
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
cipolleschicommented, Dec 15, 2022

@friyiajr, sorry for the late response. I don’t have an answer right now, I think we have to dig a little deeper into this.

1reaction
cipolleschicommented, Nov 29, 2022

Hi @friyiajr, thank you for asking the question.

What you are trying to achieve is valid, but DirectEventHandler is not the right tool. That type must only be used with Fabric Native Components and not with Native TurboModules ™.

The Codegen fails because DirectEventHandler is not a valid type for TMs.

The right way to implement what you are trying to do is by using NativeEventEmitter.

The implementation should go roughly right that:

  1. You make your TM extends to RCTEventEmitter
  2. You invoke the sendEventWithName in your TM logic
  3. In JS, you register to the event emitter to handle the events.

As an example you can look at the StatusBarManager

We know that the documentation is lacking in this respect. We are working hard to cover this use cases. Thank you for reporting the problem!

Read more comments on GitHub >

github_iconTop Results From Across the Web

react-native-codegen | Yarn - Package Manager
Fast, reliable, and secure dependency management.
Read more >
How to emit event in a Turbo Module on iOS - Stack Overflow
To emit events to RN from iOS you should make your own emitter class that is inherited from RCTEventEmitter and then init it...
Read more >
Blog - React Native
Today we are sharing an experimental cross-platform pointer API for React Native. We'll go over motivations, how it works, and its benefits to...
Read more >
iOS Guide to TurboModules in React-Native for Early Adopters
Enabling Codegen on iOS. Next, we'll need to enable the new architecture on iOS. You can do this by opening the ios folder...
Read more >
How to Support New React Native Architecture in your Mobile ...
Enabling the New NativeModule System (TurboModule) in your App. Android. 1. Enable NDK and the native build. The code-gen will generate some ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found