Skip to content

Commit ce00673

Browse files
WoLewickipull[bot]
authored andcommitted
feat: make view recycling optional on iOS (facebook#35378)
Summary: This PR resolves the potential problem of misconfiguration of components after being recycled. Some of them have custom, sometimes native (e.g. connected to VCs) logic that messes up with the concept of recycling. bypass-github-export-checks ## Changelog Added `shouldBeRecycled` field checking to `RCTComponentViewClassDescriptor `, a check for it in `_enqueueComponentViewWithComponentHandle:(ComponentHandle)componentHandle componentViewDescriptor:(RCTComponentViewDescriptor)componentViewDescriptor` method, and a default implementation in `RCTComponentViewDescriptor` returning `YES` in order not to change the default behavior. [iOS] [Added] - Add `shouldBeRecycled` method on `iOS`. Pull Request resolved: facebook#35378 Test Plan: Override this method in your custom `componentView` and see that the component is not recycled. Reviewed By: javache Differential Revision: D41381683 Pulled By: cipolleschi fbshipit-source-id: 10fd1e88f99b3608767c0b57fad462837924f02a
1 parent 46dc60a commit ce00673

File tree

4 files changed

+11
-1
lines changed

4 files changed

+11
-1
lines changed

packages/react-native/React/Fabric/Mounting/RCTComponentViewClassDescriptor.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ class RCTComponentViewClassDescriptor final {
2727
*/
2828
bool observesMountingTransactionWillMount{false};
2929
bool observesMountingTransactionDidMount{false};
30+
31+
/*
32+
* Whether the component can be recycled or not
33+
*/
34+
bool shouldBeRecycled{true};
3035
};
3136

3237
NS_ASSUME_NONNULL_END

packages/react-native/React/Fabric/Mounting/RCTComponentViewDescriptor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class RCTComponentViewDescriptor final {
2929
*/
3030
bool observesMountingTransactionWillMount{false};
3131
bool observesMountingTransactionDidMount{false};
32+
bool shouldBeRecycled{true};
3233
};
3334

3435
inline bool operator==(const RCTComponentViewDescriptor &lhs, const RCTComponentViewDescriptor &rhs)

packages/react-native/React/Fabric/Mounting/RCTComponentViewFactory.mm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ - (RCTComponentViewClassDescriptor)_componentViewClassDescriptorFromClass:(Class
9696
(bool)class_respondsToSelector(viewClass, @selector(mountingTransactionWillMount:withSurfaceTelemetry:)),
9797
.observesMountingTransactionDidMount =
9898
(bool)class_respondsToSelector(viewClass, @selector(mountingTransactionDidMount:withSurfaceTelemetry:)),
99+
.shouldBeRecycled = [viewClass respondsToSelector:@selector(shouldBeRecycled)]
100+
? (bool)[viewClass performSelector:@selector(shouldBeRecycled)]
101+
: true,
99102
};
100103
#pragma clang diagnostic pop
101104
}
@@ -210,6 +213,7 @@ - (RCTComponentViewDescriptor)createComponentViewWithComponentHandle:(facebook::
210213
.view = [viewClass new],
211214
.observesMountingTransactionWillMount = componentViewClassDescriptor.observesMountingTransactionWillMount,
212215
.observesMountingTransactionDidMount = componentViewClassDescriptor.observesMountingTransactionDidMount,
216+
.shouldBeRecycled = componentViewClassDescriptor.shouldBeRecycled,
213217
};
214218
}
215219

packages/react-native/React/Fabric/Mounting/RCTComponentViewRegistry.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ - (void)_enqueueComponentViewWithComponentHandle:(ComponentHandle)componentHandl
107107
RCTAssertMainQueue();
108108
auto &recycledViews = _recyclePool[componentHandle];
109109

110-
if (recycledViews.size() > RCTComponentViewRegistryRecyclePoolMaxSize) {
110+
if (recycledViews.size() > RCTComponentViewRegistryRecyclePoolMaxSize || !componentViewDescriptor.shouldBeRecycled) {
111111
return;
112112
}
113113

0 commit comments

Comments
 (0)