From 03fd80c9373155c86d24adc8edf35b173b2dacda Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Thu, 31 Oct 2019 14:39:41 -0700 Subject: [PATCH] Refactor RCTLegacyViewInteropComponentView Summary: Simplify logic in `RCTLegacyViewManagerInteropComponentView` by caching views that are mounted and unmounted and applying it in finalise. changelog: [internal] Reviewed By: shergin Differential Revision: D17954975 fbshipit-source-id: 11c8ec9e6eabb8a838a83f5fc2428912f4ec9523 --- ...CTLegacyViewManagerInteropComponentView.mm | 86 ++++++++----------- 1 file changed, 37 insertions(+), 49 deletions(-) diff --git a/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm b/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm index 48287492f1f..fa27cc4a2a8 100644 --- a/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm @@ -17,11 +17,8 @@ using namespace facebook::react; @implementation RCTLegacyViewManagerInteropComponentView { UIView *_paperView; - - /** - * A temporar storage of views that are being mounted to this component white paper component isn't yet ready. - */ - NSMutableArray *_insertedViews; + NSMutableDictionary *_viewsToBeMounted; + NSMutableArray *_viewsToBeUnmounted; LegacyViewManagerInteropShadowNode::ConcreteState::Shared _state; } @@ -30,7 +27,8 @@ using namespace facebook::react; if (self = [super initWithFrame:frame]) { static const auto defaultProps = std::make_shared(); _props = defaultProps; - _insertedViews = [NSMutableArray new]; + _viewsToBeMounted = [NSMutableDictionary new]; + _viewsToBeUnmounted = [NSMutableArray new]; } return self; @@ -63,33 +61,6 @@ using namespace facebook::react; } } -- (UIView *)paperView -{ - if (!_paperView) { - __weak __typeof(self) weakSelf = self; - UIView *view = [self.coordinator viewWithInterceptor:^(std::string eventName, folly::dynamic event) { - if (weakSelf) { - __typeof(self) strongSelf = weakSelf; - auto eventEmitter = - std::static_pointer_cast(strongSelf->_eventEmitter); - eventEmitter->dispatchEvent(eventName, event); - } - }]; - if (view) { - for (NSUInteger i = 0; i < _insertedViews.count; i++) { - [view insertReactSubview:_insertedViews[i] atIndex:i]; - } - - [_insertedViews removeAllObjects]; - - [view didUpdateReactSubviews]; - _paperView = view; - } - } - - return _paperView; -} - - (NSString *)componentViewName_DO_NOT_USE_THIS_IS_BROKEN { const auto &state = _state->getData(); @@ -101,28 +72,22 @@ using namespace facebook::react; - (void)prepareForRecycle { - [_insertedViews removeAllObjects]; + [_viewsToBeMounted removeAllObjects]; + [_viewsToBeUnmounted removeAllObjects]; + [_paperView removeFromSuperview]; + _paperView = nil; + _state.reset(); [super prepareForRecycle]; } - (void)mountChildComponentView:(UIView *)childComponentView index:(NSInteger)index { - if (self.paperView) { - [self.paperView insertReactSubview:childComponentView atIndex:index]; - [self.paperView didUpdateReactSubviews]; - } else { - [_insertedViews insertObject:childComponentView atIndex:index]; - } + [_viewsToBeMounted setObject:childComponentView forKey:[NSNumber numberWithInteger:index]]; } - (void)unmountChildComponentView:(UIView *)childComponentView index:(NSInteger)index { - if (self.paperView) { - [self.paperView removeReactSubview:childComponentView]; - [self.paperView didUpdateReactSubviews]; - } else { - [_insertedViews removeObjectAtIndex:index]; - } + [_viewsToBeUnmounted addObject:childComponentView]; } + (ComponentDescriptorProvider)componentDescriptorProvider @@ -139,13 +104,36 @@ using namespace facebook::react; { [super finalizeUpdates:updateMask]; - if (!self.contentView) { - self.contentView = self.paperView; + if (!_paperView) { + __weak __typeof(self) weakSelf = self; + _paperView = [self.coordinator viewWithInterceptor:^(std::string eventName, folly::dynamic event) { + if (weakSelf) { + __typeof(self) strongSelf = weakSelf; + auto eventEmitter = + std::static_pointer_cast(strongSelf->_eventEmitter); + eventEmitter->dispatchEvent(eventName, event); + } + }]; + self.contentView = _paperView; } + for (NSNumber *key in _viewsToBeMounted) { + [_paperView insertReactSubview:_viewsToBeMounted[key] atIndex:key.integerValue]; + } + + [_viewsToBeMounted removeAllObjects]; + + for (UIView *view in _viewsToBeUnmounted) { + [_paperView removeReactSubview:view]; + } + + [_viewsToBeUnmounted removeAllObjects]; + + [_paperView didUpdateReactSubviews]; + if (updateMask & RNComponentViewUpdateMaskProps) { const auto &newProps = *std::static_pointer_cast(_props); - [self.coordinator setProps:newProps.otherProps forView:self.paperView]; + [self.coordinator setProps:newProps.otherProps forView:_paperView]; } }