diff --git a/packages/react-native/React/Fabric/Mounting/RCTComponentViewClassDescriptor.h b/packages/react-native/React/Fabric/Mounting/RCTComponentViewClassDescriptor.h index b03a4642a98123..3bc159229f7429 100644 --- a/packages/react-native/React/Fabric/Mounting/RCTComponentViewClassDescriptor.h +++ b/packages/react-native/React/Fabric/Mounting/RCTComponentViewClassDescriptor.h @@ -27,6 +27,11 @@ class RCTComponentViewClassDescriptor final { */ bool observesMountingTransactionWillMount{false}; bool observesMountingTransactionDidMount{false}; + + /* + * Whether the component can be recycled or not + */ + bool shouldBeRecycled{true}; }; NS_ASSUME_NONNULL_END diff --git a/packages/react-native/React/Fabric/Mounting/RCTComponentViewDescriptor.h b/packages/react-native/React/Fabric/Mounting/RCTComponentViewDescriptor.h index 3ca65d18fcb1f1..fd1c4b9feb0cd8 100644 --- a/packages/react-native/React/Fabric/Mounting/RCTComponentViewDescriptor.h +++ b/packages/react-native/React/Fabric/Mounting/RCTComponentViewDescriptor.h @@ -29,6 +29,7 @@ class RCTComponentViewDescriptor final { */ bool observesMountingTransactionWillMount{false}; bool observesMountingTransactionDidMount{false}; + bool shouldBeRecycled{true}; }; inline bool operator==(const RCTComponentViewDescriptor &lhs, const RCTComponentViewDescriptor &rhs) diff --git a/packages/react-native/React/Fabric/Mounting/RCTComponentViewFactory.mm b/packages/react-native/React/Fabric/Mounting/RCTComponentViewFactory.mm index 51545202a3b5b9..ebd9d5a6e9e1d6 100644 --- a/packages/react-native/React/Fabric/Mounting/RCTComponentViewFactory.mm +++ b/packages/react-native/React/Fabric/Mounting/RCTComponentViewFactory.mm @@ -96,6 +96,9 @@ - (RCTComponentViewClassDescriptor)_componentViewClassDescriptorFromClass:(Class (bool)class_respondsToSelector(viewClass, @selector(mountingTransactionWillMount:withSurfaceTelemetry:)), .observesMountingTransactionDidMount = (bool)class_respondsToSelector(viewClass, @selector(mountingTransactionDidMount:withSurfaceTelemetry:)), + .shouldBeRecycled = [viewClass respondsToSelector:@selector(shouldBeRecycled)] + ? (bool)[viewClass performSelector:@selector(shouldBeRecycled)] + : true, }; #pragma clang diagnostic pop } @@ -210,6 +213,7 @@ - (RCTComponentViewDescriptor)createComponentViewWithComponentHandle:(facebook:: .view = [viewClass new], .observesMountingTransactionWillMount = componentViewClassDescriptor.observesMountingTransactionWillMount, .observesMountingTransactionDidMount = componentViewClassDescriptor.observesMountingTransactionDidMount, + .shouldBeRecycled = componentViewClassDescriptor.shouldBeRecycled, }; } diff --git a/packages/react-native/React/Fabric/Mounting/RCTComponentViewRegistry.mm b/packages/react-native/React/Fabric/Mounting/RCTComponentViewRegistry.mm index e78e8ae53342fd..74ebc3160ea430 100644 --- a/packages/react-native/React/Fabric/Mounting/RCTComponentViewRegistry.mm +++ b/packages/react-native/React/Fabric/Mounting/RCTComponentViewRegistry.mm @@ -107,7 +107,7 @@ - (void)_enqueueComponentViewWithComponentHandle:(ComponentHandle)componentHandl RCTAssertMainQueue(); auto &recycledViews = _recyclePool[componentHandle]; - if (recycledViews.size() > RCTComponentViewRegistryRecyclePoolMaxSize) { + if (recycledViews.size() > RCTComponentViewRegistryRecyclePoolMaxSize || !componentViewDescriptor.shouldBeRecycled) { return; }