tezvyn:

React Native: Sending Events from Native to JavaScript

AI-drafted, machine-checkedSource: reactnative.devintermediate

Think of it as a webhook from native code to your JavaScript UI. Native modules can push updates to JS without being called, enabling reactive UIs for long-running tasks or platform-level events.

WHY IT EXISTS JavaScript is single-threaded and cannot block on long-running native operations without freezing the UI. To keep an app responsive, native code needs a way to signal back to JavaScript when an asynchronous task is complete or a system event has occurred, without JavaScript having to constantly poll for status updates.

THE MENTAL MODEL Treat it like a subscription or a webhook. Your JavaScript code subscribes to a specific event channel exposed by a native module. When something interesting happens on the native side—a file finishes downloading, a sensor value changes, a new item is saved to native storage—the native module "emits" an event on that channel, triggering a callback function in your JavaScript code.

HOW IT WORKS The process has three main parts. First, you declare the event in your TurboModule's TypeScript or Flow spec file using CodegenTypes.EventEmitter<PayloadType>. This defines the event's name and the shape of the data it will carry. Second, you run Codegen, which generates the necessary native interface code for both Android and iOS, bridging the native platform and your JS code. Finally, in your React component, you use a useEffect hook to subscribe to the event (e.g., NativeModule.onMyEvent(...)) and define the callback function to handle it.

WHEN TO USE IT Use this pattern for asynchronous, one-way communication from native to JS. It's ideal for notifying the UI about the progress or completion of long-running native tasks (like network requests or file processing), or for reacting to platform-specific events that your app needs to know about, such as changes in device connectivity or system-level notifications.

WHEN NOT TO USE IT Do not use events for synchronous data retrieval. If your JavaScript code needs to call a native function and get an immediate result, a standard native method with a return value or a Promise is the correct approach. Events are for push-based communication from native to JS, not for request-response cycles initiated by JavaScript.

ONE CANONICAL EXAMPLE To notify JS when a new key is added to a native key-value store, you first define onKeyAdded: CodegenTypes.EventEmitter<KeyValuePair> in the module's spec. After running Codegen, your React component subscribes using useEffect. Inside the effect, you call NativeLocalStorage.onKeyAdded((pair) => { ... }) and store the returned subscription object, often in a useRef. Crucially, the effect's cleanup function must call subscription.remove() on that object to prevent memory leaks when the component unmounts.

Read the original → reactnative.dev

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.