mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
feat: make view recycling optional on iOS (#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: https://github.com/facebook/react-native/pull/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
This commit is contained in:
committed by
Facebook GitHub Bot
parent
cfeb43eaa2
commit
613a5a7597
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -96,6 +96,9 @@ static Class<RCTComponentViewProtocol> RCTComponentViewClassWithName(const char
|
||||
(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 @@ static Class<RCTComponentViewProtocol> RCTComponentViewClassWithName(const char
|
||||
.view = [viewClass new],
|
||||
.observesMountingTransactionWillMount = componentViewClassDescriptor.observesMountingTransactionWillMount,
|
||||
.observesMountingTransactionDidMount = componentViewClassDescriptor.observesMountingTransactionDidMount,
|
||||
.shouldBeRecycled = componentViewClassDescriptor.shouldBeRecycled,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ const NSInteger RCTComponentViewRegistryRecyclePoolMaxSize = 1024;
|
||||
RCTAssertMainQueue();
|
||||
auto &recycledViews = _recyclePool[componentHandle];
|
||||
|
||||
if (recycledViews.size() > RCTComponentViewRegistryRecyclePoolMaxSize) {
|
||||
if (recycledViews.size() > RCTComponentViewRegistryRecyclePoolMaxSize || !componentViewDescriptor.shouldBeRecycled) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user