mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Queue the event for preallocated but not mounted view to dispatch later
Summary: This diff fixed an edge case that event dispatching is failed after pre-allocation of a view and before the view is mounted. When a cached image is loaded, we will dispatch the event to JS immediately. This is could happen after the view is created during pre-allocation phase, when the event emitter is not instantiated yet. In that case, we will see [an error](https://github.com/facebook/react-native/blob/main/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java#L927) and the event will effectively be ignored. To fix that we introduced a queue in this diff for those events. They will be dispatched in order when the view is mounted and the event emitter is non-null. Changelog: [Android][Fixed] - Fixed an edge case that event dispatching is failed after pre-allocation of a view and before the view is mounted. Reviewed By: mullender Differential Revision: D36331914 fbshipit-source-id: cd065b0b36978cb5f0aac793d8d16f07a48f0881
This commit is contained in:
committed by
Facebook GitHub Bot
parent
644fe430fd
commit
a093fe5f2f
@@ -59,6 +59,7 @@ import com.facebook.react.fabric.events.FabricEventEmitter;
|
||||
import com.facebook.react.fabric.mounting.MountItemDispatcher;
|
||||
import com.facebook.react.fabric.mounting.MountingManager;
|
||||
import com.facebook.react.fabric.mounting.SurfaceMountingManager;
|
||||
import com.facebook.react.fabric.mounting.SurfaceMountingManager.ViewEvent;
|
||||
import com.facebook.react.fabric.mounting.mountitems.DispatchIntCommandMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.DispatchStringCommandMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.IntBufferBatchMountItem;
|
||||
@@ -923,8 +924,18 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
EventEmitterWrapper eventEmitter = mMountingManager.getEventEmitter(surfaceId, reactTag);
|
||||
|
||||
if (eventEmitter == null) {
|
||||
// This can happen if the view has disappeared from the screen (because of async events)
|
||||
FLog.d(TAG, "Unable to invoke event: " + eventName + " for reactTag: " + reactTag);
|
||||
if (ReactFeatureFlags.enableFabricPendingEventQueue
|
||||
&& mMountingManager.getViewExists(reactTag)) {
|
||||
// The view is preallocated and created. However, it hasn't been mounted yet. We will have
|
||||
// access to the event emitter later when the view is mounted. For now just save the event
|
||||
// in the view state and trigger it later.
|
||||
mMountingManager.enqueuePendingEvent(
|
||||
reactTag,
|
||||
new ViewEvent(eventName, params, eventCategory, canCoalesceEvent, customCoalesceKey));
|
||||
} else {
|
||||
// This can happen if the view has disappeared from the screen (because of async events)
|
||||
FLog.d(TAG, "Unable to invoke event: " + eventName + " for reactTag: " + reactTag);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user