Deep Dive into React Native’s Native Event‑Handling Path: From RCTRootView to the JavaScript Bridge
This article thoroughly analyzes React Native’s native event‑handling pipeline, explaining how RCTRootView creates RCTRootContentView and RCTTouchHandler, detailing the touchesBegan/touchesMoved/touchesEnded implementations, and tracing the flow through _updateAndDispatchTouches, RCTEventDispatcher, and the bridge that finally invokes JavaScript callbacks.
React Native’s event system starts with RCTRootView , which creates a RCTRootContentView that registers itself as the true root view via _bridge.uiManager registerRootView. Inside the content view a RCTTouchHandler (a subclass of UIGestureRecognizer) is attached to intercept all touch events.
When a touch begins, touchesBegan:withEvent: is called on RCTTouchHandler . The method records new touches, updates the internal touch state, and forwards the event to _updateAndDispatchTouches:eventName: with the name "touchStart". Similar logic exists for touchesMoved, touchesEnded, and touchesCancelled, each invoking _updateAndDispatchTouches with the appropriate event name.
The core of the native side is the _updateAndDispatchTouches:eventName: method. It builds an array of changed touch indexes, creates a copy of the current touch data, determines whether the event can be coalesced, and finally constructs an RCTTouchEvent object:
- (void)_updateAndDispatchTouches:(NSSet<UITouch *> *)touches eventName:(NSString *)eventName { … }The event is then handed to RCTEventDispatcher via sendEvent:. The dispatcher notifies observers, checks for coalescing, queues the event ID, and schedules a dispatch on the JavaScript thread. - (void)sendEvent:(id<RCTEvent>)event { … } During dispatch, flushEventsQueue iterates over the queued event IDs, retrieves each event, and calls dispatchEvent:. This method logs the event name and enqueues a JavaScript call through the bridge:
- (void)dispatchEvent:(id<RCTEvent>)event { NSLog(@"xiaowei.li:%@", event.eventName); [_bridge enqueueJSCall:[event class] moduleDotMethod args:[event arguments]]; }The bridge’s enqueueJSCall:method:args:completion: validates the bridge, splits the moduleDotMethod string, and ultimately invokes the JavaScript function via the native instance:
- (void)enqueueJSCall:(NSString *)module method:(NSString *)method args:(NSArray *)args completion:(dispatch_block_t)completion { if (!self.valid) return; [_reactInstance callJSFunction:[module UTF8String] [method UTF8String] convertIdToFollyDynamic(args ?: @[])]; }Thus, the touch event travels from the iOS gesture recognizer, through a series of native Objective‑C classes, into a serialized event object, and finally reaches JavaScript where the React Native runtime processes it. The article also lists related classes and protocols such as RCTRootView , RCTTouchHandler , RCTEventDispatcher , RCTBridge , RCTBatchedBridge , and RCTCxxBridge .
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Qunar Tech Salon
Qunar Tech Salon is a learning and exchange platform for Qunar engineers and industry peers. We share cutting-edge technology trends and topics, providing a free platform for mid-to-senior technical professionals to exchange and learn.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
