Fabric: Introducing -[RCTComponentViewProtocol finalizeUpdates:]

Summary:
The new method is being called right after all update methods were called for a particular component view.
It is useful for performing updates that require knowledge of several independent aspects of the compound mounting change (e.g. props *and* layout constraints).

Reviewed By: JoshuaGross

Differential Revision: D14896801

fbshipit-source-id: 485d8c97d81d7a2ad7a7afc209094c328da6ef3c
This commit is contained in:
Valentin Shergin
2019-04-16 07:23:05 -07:00
committed by Facebook Github Bot
parent 184cfd5594
commit c79db53a9a
4 changed files with 55 additions and 1 deletions

View File

@@ -16,7 +16,22 @@
NS_ASSUME_NONNULL_BEGIN
/**
/*
* Bitmask for all types of possible updates performing during mounting.
*/
typedef NS_OPTIONS(NSInteger, RNComponentViewUpdateMask) {
RNComponentViewUpdateMaskNone = 0,
RNComponentViewUpdateMaskProps = 1 << 0,
RNComponentViewUpdateMaskEventEmitter = 1 << 1,
RNComponentViewUpdateMaskLocalData = 1 << 2,
RNComponentViewUpdateMaskState = 1 << 3,
RNComponentViewUpdateMaskLayoutMetrics = 1 << 4,
RNComponentViewUpdateMaskAll = RNComponentViewUpdateMaskProps | RNComponentViewUpdateMaskEventEmitter |
RNComponentViewUpdateMaskLocalData | RNComponentViewUpdateMaskState | RNComponentViewUpdateMaskLayoutMetrics
};
/*
* Represents a `UIView` instance managed by React.
* All methods are non-@optional.
* `UIView+ComponentViewProtocol` category provides default implementation
@@ -78,6 +93,13 @@ NS_ASSUME_NONNULL_BEGIN
- (void)updateLayoutMetrics:(facebook::react::LayoutMetrics)layoutMetrics
oldLayoutMetrics:(facebook::react::LayoutMetrics)oldLayoutMetrics;
/*
* Called right after all update methods were called for a particular component view.
* Useful for performing updates that require knowledge of several independent aspects of the compound mounting change
* (e.g. props *and* layout constraints).
*/
- (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask;
/*
* Called right after the component view is moved to a recycle pool.
* Receiver must reset any local state and release associated

View File

@@ -123,6 +123,17 @@ static void RNUpdateStateMountInstruction(ShadowViewMutation const &mutation, RC
[componentView updateState:newShadowView.state oldState:oldShadowView.state];
}
// `Finalize Updates` instruction
static void RNFinalizeUpdatesMountInstruction(
ShadowViewMutation const &mutation,
RNComponentViewUpdateMask mask,
RCTComponentViewRegistry *registry)
{
auto const &newShadowView = mutation.newChildShadowView;
UIView<RCTComponentViewProtocol> *componentView = [registry componentViewByTag:newShadowView.tag];
[componentView finalizeUpdates:mask];
}
// `Update` instruction
static void RNPerformMountInstructions(ShadowViewMutationList const &mutations, RCTComponentViewRegistry *registry)
{
@@ -144,6 +155,7 @@ static void RNPerformMountInstructions(ShadowViewMutationList const &mutations,
RNUpdateLocalDataMountInstruction(mutation, registry);
RNUpdateStateMountInstruction(mutation, registry);
RNUpdateLayoutMetricsMountInstruction(mutation, registry);
RNFinalizeUpdatesMountInstruction(mutation, RNComponentViewUpdateMaskAll, registry);
RNInsertMountInstruction(mutation, registry);
break;
}
@@ -154,21 +166,34 @@ static void RNPerformMountInstructions(ShadowViewMutationList const &mutations,
case ShadowViewMutation::Update: {
auto const &oldChildShadowView = mutation.oldChildShadowView;
auto const &newChildShadowView = mutation.newChildShadowView;
auto mask = RNComponentViewUpdateMask{};
if (oldChildShadowView.props != newChildShadowView.props) {
RNUpdatePropsMountInstruction(mutation, registry);
mask |= RNComponentViewUpdateMaskProps;
}
if (oldChildShadowView.eventEmitter != newChildShadowView.eventEmitter) {
RNUpdateEventEmitterMountInstruction(mutation, registry);
mask |= RNComponentViewUpdateMaskEventEmitter;
}
if (oldChildShadowView.localData != newChildShadowView.localData) {
RNUpdateLocalDataMountInstruction(mutation, registry);
mask |= RNComponentViewUpdateMaskLocalData;
}
if (oldChildShadowView.state != newChildShadowView.state) {
RNUpdateStateMountInstruction(mutation, registry);
mask |= RNComponentViewUpdateMaskState;
}
if (oldChildShadowView.layoutMetrics != newChildShadowView.layoutMetrics) {
RNUpdateLayoutMetricsMountInstruction(mutation, registry);
mask |= RNComponentViewUpdateMaskLayoutMetrics;
}
if (mask != RNComponentViewUpdateMaskNone) {
RNFinalizeUpdatesMountInstruction(mutation, mask, registry);
}
break;
}
}

View File

@@ -32,6 +32,8 @@ NS_ASSUME_NONNULL_BEGIN
- (void)updateLayoutMetrics:(facebook::react::LayoutMetrics)layoutMetrics
oldLayoutMetrics:(facebook::react::LayoutMetrics)oldLayoutMetrics;
- (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask;
- (void)prepareForRecycle;
- (facebook::react::SharedProps)props;

View File

@@ -82,6 +82,11 @@ using namespace facebook::react;
}
}
- (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask
{
// Default implementation does nothing.
}
- (void)prepareForRecycle
{
// Default implementation does nothing.