diff --git a/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-itest.js b/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-itest.js
index 0fd23272409d42..e36beafdfe382f 100644
--- a/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-itest.js
+++ b/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-itest.js
@@ -191,15 +191,126 @@ test('animate layout props and rerender', () => {
_setWidth(200);
});
+ // TODO: getFabricUpdateProps is not working with the cloneMutliple method
+ // expect(Fantom.unstable_getFabricUpdateProps(viewElement).height).toBe(50);
+ expect(root.getRenderedOutput({props: ['height', 'width']}).toJSX()).toEqual(
+ ,
+ );
+
+ Fantom.unstable_produceFramesForDuration(500);
+
// TODO: this shouldn't be neccessary since animation should be stopped after duration
Fantom.runTask(() => {
_heightAnimation?.stop();
});
+ expect(root.getRenderedOutput({props: ['height', 'width']}).toJSX()).toEqual(
+ ,
+ );
+
+ Fantom.runTask(() => {
+ _setWidth(300);
+ });
+
+ expect(root.getRenderedOutput({props: ['height', 'width']}).toJSX()).toEqual(
+ ,
+ );
+});
+
+test('animate non-layout props and rerender', () => {
+ const viewRef = createRef();
+
+ let _animatedOpacity;
+ let _opacityAnimation;
+ let _setWidth;
+
+ function MyApp() {
+ const animatedOpacity = useAnimatedValue(0);
+ const [width, setWidth] = useState(100);
+ _animatedOpacity = animatedOpacity;
+ _setWidth = setWidth;
+ return (
+
+ );
+ }
+
+ const root = Fantom.createRoot();
+
+ Fantom.runTask(() => {
+ root.render();
+ });
+
+ const viewElement = ensureInstance(viewRef.current, ReactNativeElement);
+
+ Fantom.runTask(() => {
+ _opacityAnimation = Animated.timing(_animatedOpacity, {
+ toValue: 0.5,
+ duration: 1000,
+ useNativeDriver: true,
+ }).start();
+ });
+
+ Fantom.unstable_produceFramesForDuration(500);
+
+ // TODO: rendered output should be at this point, but synchronous updates are not captured by fantom
+ expect(root.getRenderedOutput({props: ['width']}).toJSX()).toEqual(
+ ,
+ );
+
+ expect(
+ Fantom.unstable_getDirectManipulationProps(viewElement).opacity,
+ ).toBeCloseTo(0.25, 0.001);
+
+ // Re-render
+ Fantom.runTask(() => {
+ _setWidth(150);
+ });
+
+ expect(root.getRenderedOutput({props: ['opacity', 'width']}).toJSX()).toEqual(
+ ,
+ );
+
+ Fantom.runTask(() => {
+ _setWidth(200);
+ });
+
// TODO: getFabricUpdateProps is not working with the cloneMutliple method
// expect(Fantom.unstable_getFabricUpdateProps(viewElement).height).toBe(50);
- expect(root.getRenderedOutput({props: ['height', 'width']}).toJSX()).toEqual(
- ,
+ expect(root.getRenderedOutput({props: ['opacity', 'width']}).toJSX()).toEqual(
+ ,
+ );
+
+ Fantom.unstable_produceFramesForDuration(500);
+
+ // TODO: this shouldn't be neccessary since animation should be stopped after duration
+ Fantom.runTask(() => {
+ _opacityAnimation?.stop();
+ });
+
+ // TODO: T246961305 rendered output should be at this point
+ expect(root.getRenderedOutput({props: ['width']}).toJSX()).toEqual(
+ ,
+ );
+
+ expect(Fantom.unstable_getDirectManipulationProps(viewElement).opacity).toBe(
+ 0.5,
+ );
+
+ // Re-render
+ Fantom.runTask(() => {
+ _setWidth(300);
+ });
+
+ expect(root.getRenderedOutput({props: ['opacity', 'width']}).toJSX()).toEqual(
+ ,
);
});
@@ -298,3 +409,72 @@ test('animate layout props and rerender in many components', () => {
,
);
});
+
+test('animate width, height and opacity at once', () => {
+ const viewRef = createRef();
+ allowStyleProp('width');
+ allowStyleProp('height');
+
+ let _animatedWidth;
+ let _animatedHeight;
+ let _animatedOpacity;
+ let _parallelAnimation;
+
+ function MyApp() {
+ const animatedWidth = useAnimatedValue(100);
+ const animatedHeight = useAnimatedValue(100);
+ const animatedOpacity = useAnimatedValue(1);
+ _animatedWidth = animatedWidth;
+ _animatedHeight = animatedHeight;
+ _animatedOpacity = animatedOpacity;
+ return (
+
+ );
+ }
+
+ const root = Fantom.createRoot();
+
+ Fantom.runTask(() => {
+ root.render();
+ });
+
+ Fantom.runTask(() => {
+ _parallelAnimation = Animated.parallel([
+ Animated.timing(_animatedWidth, {
+ toValue: 200,
+ duration: 100,
+ useNativeDriver: true,
+ }),
+ Animated.timing(_animatedHeight, {
+ toValue: 200,
+ duration: 100,
+ useNativeDriver: true,
+ }),
+ Animated.timing(_animatedOpacity, {
+ toValue: 0.5,
+ duration: 100,
+ useNativeDriver: true,
+ }),
+ ]).start();
+ });
+
+ Fantom.unstable_produceFramesForDuration(100);
+
+ // TODO: this shouldn't be neccessary since animation should be stopped after duration
+ Fantom.runTask(() => {
+ _parallelAnimation?.stop();
+ });
+
+ expect(
+ root.getRenderedOutput({props: ['width', 'height', 'opacity']}).toJSX(),
+ ).toEqual();
+});
diff --git a/packages/react-native/ReactCommon/react/renderer/animated/NativeAnimatedNodesManager.cpp b/packages/react-native/ReactCommon/react/renderer/animated/NativeAnimatedNodesManager.cpp
index a17966d285d402..7341352e0cc336 100644
--- a/packages/react-native/ReactCommon/react/renderer/animated/NativeAnimatedNodesManager.cpp
+++ b/packages/react-native/ReactCommon/react/renderer/animated/NativeAnimatedNodesManager.cpp
@@ -1007,39 +1007,41 @@ AnimationMutations NativeAnimatedNodesManager::pullAnimationMutations() {
}
}
- for (auto& [tag, props] : updateViewPropsDirect_) {
- propsBuilder.storeDynamic(props);
- mutations.push_back(
- AnimationMutation{tag, nullptr, propsBuilder.get()});
- containsChange = true;
- }
{
std::lock_guard lock(tagToShadowNodeFamilyMutex_);
+ for (auto& [tag, props] : updateViewPropsDirect_) {
+ auto familyIt = tagToShadowNodeFamily_.find(tag);
+ if (familyIt == tagToShadowNodeFamily_.end()) {
+ continue;
+ }
+
+ auto weakFamily = familyIt->second;
+ if (auto family = weakFamily.lock()) {
+ propsBuilder.storeDynamic(props);
+ mutations.batch.push_back(
+ AnimationMutation{
+ .tag = tag,
+ .family = family,
+ .props = propsBuilder.get(),
+ });
+ }
+ containsChange = true;
+ }
for (auto& [tag, props] : updateViewProps_) {
auto familyIt = tagToShadowNodeFamily_.find(tag);
if (familyIt == tagToShadowNodeFamily_.end()) {
continue;
}
- if (auto family = familyIt->second.lock()) {
- // C++ Animated produces props in the form of a folly::dynamic, so
- // it wouldn't make sense to unpack it here. However, for the
- // purposes of testing, we want to be able to use the statically
- // typed AnimationMutation. At a later stage we will instead just
- // pass the dynamic directly to propsBuilder and the new API could
- // be used by 3rd party libraries or in the fututre by Animated.
- if (props.find("width") != props.items().end()) {
- propsBuilder.setWidth(
- yoga::Style::SizeLength::points(props["width"].asDouble()));
- }
- if (props.find("height") != props.items().end()) {
- propsBuilder.setHeight(
- yoga::Style::SizeLength::points(props["height"].asDouble()));
- }
- mutations.push_back(
+
+ auto weakFamily = familyIt->second;
+ if (auto family = weakFamily.lock()) {
+ propsBuilder.storeDynamic(props);
+ mutations.batch.push_back(
AnimationMutation{
.tag = tag,
.family = family,
.props = propsBuilder.get(),
+ .hasLayoutUpdates = true,
});
}
containsChange = true;
@@ -1074,33 +1076,46 @@ AnimationMutations NativeAnimatedNodesManager::pullAnimationMutations() {
isEventAnimationInProgress_ = false;
- for (auto& [tag, props] : updateViewPropsDirect_) {
- propsBuilder.storeDynamic(props);
- mutations.push_back(
- AnimationMutation{
- .tag = tag,
- .family = nullptr,
- .props = propsBuilder.get(),
- });
- }
{
std::lock_guard lock(tagToShadowNodeFamilyMutex_);
+ for (auto& [tag, props] : updateViewPropsDirect_) {
+ auto familyIt = tagToShadowNodeFamily_.find(tag);
+ if (familyIt == tagToShadowNodeFamily_.end()) {
+ continue;
+ }
+
+ auto weakFamily = familyIt->second;
+ if (auto family = weakFamily.lock()) {
+ propsBuilder.storeDynamic(props);
+ mutations.batch.push_back(
+ AnimationMutation{
+ .tag = tag,
+ .family = family,
+ .props = propsBuilder.get(),
+ });
+ }
+ }
for (auto& [tag, props] : updateViewProps_) {
auto familyIt = tagToShadowNodeFamily_.find(tag);
if (familyIt == tagToShadowNodeFamily_.end()) {
continue;
}
- if (auto family = familyIt->second.lock()) {
+
+ auto weakFamily = familyIt->second;
+ if (auto family = weakFamily.lock()) {
propsBuilder.storeDynamic(props);
- mutations.push_back(
+ mutations.batch.push_back(
AnimationMutation{
.tag = tag,
.family = family,
.props = propsBuilder.get(),
+ .hasLayoutUpdates = true,
});
}
}
}
+ updateViewProps_.clear();
+ updateViewPropsDirect_.clear();
}
} else {
// There is no active animation. Stop the render callback.
diff --git a/packages/react-native/ReactCommon/react/renderer/animated/NativeAnimatedNodesManagerProvider.cpp b/packages/react-native/ReactCommon/react/renderer/animated/NativeAnimatedNodesManagerProvider.cpp
index 569f662d9753d4..bf8bad41ba96c2 100644
--- a/packages/react-native/ReactCommon/react/renderer/animated/NativeAnimatedNodesManagerProvider.cpp
+++ b/packages/react-native/ReactCommon/react/renderer/animated/NativeAnimatedNodesManagerProvider.cpp
@@ -145,28 +145,30 @@ NativeAnimatedNodesManagerProvider::getOrCreate(
uiManager->setNativeAnimatedDelegate(nativeAnimatedDelegate_);
- animatedMountingOverrideDelegate_ =
- std::make_shared(
- *nativeAnimatedNodesManager_, *scheduler);
-
- // Register on existing surfaces
- uiManager->getShadowTreeRegistry().enumerate(
- [animatedMountingOverrideDelegate =
- std::weak_ptr(
- animatedMountingOverrideDelegate_)](
- const ShadowTree& shadowTree, bool& /*stop*/) {
- shadowTree.getMountingCoordinator()->setMountingOverrideDelegate(
- animatedMountingOverrideDelegate);
- });
- // Register on surfaces started in the future
- uiManager->setOnSurfaceStartCallback(
- [animatedMountingOverrideDelegate =
- std::weak_ptr(
- animatedMountingOverrideDelegate_)](
- const ShadowTree& shadowTree) {
- shadowTree.getMountingCoordinator()->setMountingOverrideDelegate(
- animatedMountingOverrideDelegate);
- });
+ if (!ReactNativeFeatureFlags::useSharedAnimatedBackend()) {
+ animatedMountingOverrideDelegate_ =
+ std::make_shared(
+ *nativeAnimatedNodesManager_, *scheduler);
+
+ // Register on existing surfaces
+ uiManager->getShadowTreeRegistry().enumerate(
+ [animatedMountingOverrideDelegate =
+ std::weak_ptr(
+ animatedMountingOverrideDelegate_)](
+ const ShadowTree& shadowTree, bool& /*stop*/) {
+ shadowTree.getMountingCoordinator()->setMountingOverrideDelegate(
+ animatedMountingOverrideDelegate);
+ });
+ // Register on surfaces started in the future
+ uiManager->setOnSurfaceStartCallback(
+ [animatedMountingOverrideDelegate =
+ std::weak_ptr(
+ animatedMountingOverrideDelegate_)](
+ const ShadowTree& shadowTree) {
+ shadowTree.getMountingCoordinator()->setMountingOverrideDelegate(
+ animatedMountingOverrideDelegate);
+ });
+ }
}
return nativeAnimatedNodesManager_;
}
diff --git a/packages/react-native/ReactCommon/react/renderer/animationbackend/AnimatedPropsRegistry.cpp b/packages/react-native/ReactCommon/react/renderer/animationbackend/AnimatedPropsRegistry.cpp
index bfddaeaf427c72..09ee3620c6fd53 100644
--- a/packages/react-native/ReactCommon/react/renderer/animationbackend/AnimatedPropsRegistry.cpp
+++ b/packages/react-native/ReactCommon/react/renderer/animationbackend/AnimatedPropsRegistry.cpp
@@ -35,6 +35,18 @@ void AnimatedPropsRegistry::update(
auto& snapshot = it->second;
auto& viewProps = snapshot->props;
+ if (animatedProps.rawProps) {
+ const auto& newRawProps = *animatedProps.rawProps;
+ auto& currentRawProps = snapshot->rawProps;
+
+ if (currentRawProps) {
+ auto newRawPropsDynamic = newRawProps.toDynamic();
+ currentRawProps->merge_patch(newRawPropsDynamic);
+ } else {
+ currentRawProps =
+ std::make_unique(newRawProps.toDynamic());
+ }
+ }
for (const auto& animatedProp : animatedProps.props) {
snapshot->propNames.insert(animatedProp->propName);
cloneProp(viewProps, *animatedProp);
@@ -58,6 +70,13 @@ AnimatedPropsRegistry::getMap(SurfaceId surfaceId) {
map.insert_or_assign(tag, std::move(propsSnapshot));
} else {
auto& currentSnapshot = currentIt->second;
+ if (propsSnapshot->rawProps) {
+ if (currentSnapshot->rawProps) {
+ currentSnapshot->rawProps->merge_patch(*propsSnapshot->rawProps);
+ } else {
+ currentSnapshot->rawProps = std::move(propsSnapshot->rawProps);
+ }
+ }
for (auto& propName : propsSnapshot->propNames) {
currentSnapshot->propNames.insert(propName);
updateProp(propName, currentSnapshot->props, *propsSnapshot);
diff --git a/packages/react-native/ReactCommon/react/renderer/animationbackend/AnimatedPropsRegistry.h b/packages/react-native/ReactCommon/react/renderer/animationbackend/AnimatedPropsRegistry.h
index 3a982ef2245c2f..6df1dc6fb088ce 100644
--- a/packages/react-native/ReactCommon/react/renderer/animationbackend/AnimatedPropsRegistry.h
+++ b/packages/react-native/ReactCommon/react/renderer/animationbackend/AnimatedPropsRegistry.h
@@ -19,6 +19,7 @@ namespace facebook::react {
struct PropsSnapshot {
BaseViewProps props;
std::unordered_set propNames;
+ std::unique_ptr rawProps;
};
struct SurfaceContext {
@@ -29,6 +30,7 @@ struct SurfaceContext {
struct SurfaceUpdates {
std::unordered_set families;
std::unordered_map propsMap;
+ bool hasLayoutUpdates{false};
};
using SnapshotMap = std::unordered_map>;
diff --git a/packages/react-native/ReactCommon/react/renderer/animationbackend/AnimationBackend.cpp b/packages/react-native/ReactCommon/react/renderer/animationbackend/AnimationBackend.cpp
index ddf079c3800fbe..b06fe1d92fb121 100644
--- a/packages/react-native/ReactCommon/react/renderer/animationbackend/AnimationBackend.cpp
+++ b/packages/react-native/ReactCommon/react/renderer/animationbackend/AnimationBackend.cpp
@@ -6,6 +6,7 @@
*/
#include "AnimationBackend.h"
+#include
#include
#include
#include
@@ -60,17 +61,6 @@ static inline Props::Shared cloneProps(
return newProps;
}
-static inline bool mutationHasLayoutUpdates(
- facebook::react::AnimationMutation& mutation) {
- for (auto& animatedProp : mutation.props.props) {
- // TODO: there should also be a check for the dynamic part
- if (layoutProps.contains(animatedProp->propName)) {
- return true;
- }
- }
- return false;
-}
-
AnimationBackend::AnimationBackend(
StartOnRenderCallback&& startOnRenderCallback,
StopOnRenderCallback&& stopOnRenderCallback,
@@ -86,31 +76,30 @@ AnimationBackend::AnimationBackend(
commitHook_(uiManager, animatedPropsRegistry_) {}
void AnimationBackend::onAnimationFrame(double timestamp) {
- std::unordered_map synchronousUpdates;
std::unordered_map surfaceUpdates;
- bool hasAnyLayoutUpdates = false;
for (auto& callback : callbacks) {
auto muatations = callback(static_cast(timestamp));
- for (auto& mutation : muatations) {
- hasAnyLayoutUpdates |= mutationHasLayoutUpdates(mutation);
+ for (auto& mutation : muatations.batch) {
const auto family = mutation.family;
- if (family != nullptr) {
- auto& [families, updates] = surfaceUpdates[family->getSurfaceId()];
- families.insert(family.get());
- updates[mutation.tag] = std::move(mutation.props);
- } else {
- synchronousUpdates[mutation.tag] = std::move(mutation.props);
- }
+ react_native_assert(family != nullptr);
+
+ auto& [families, updates, hasLayoutUpdates] =
+ surfaceUpdates[family->getSurfaceId()];
+ hasLayoutUpdates |= mutation.hasLayoutUpdates;
+ families.insert(family.get());
+ updates[mutation.tag] = std::move(mutation.props);
}
}
animatedPropsRegistry_->update(surfaceUpdates);
- if (hasAnyLayoutUpdates) {
- commitUpdates(surfaceUpdates);
- } else {
- synchronouslyUpdateProps(synchronousUpdates);
+ for (auto& [surfaceId, updates] : surfaceUpdates) {
+ if (updates.hasLayoutUpdates) {
+ commitUpdates(surfaceId, updates);
+ } else {
+ synchronouslyUpdateProps(updates.propsMap);
+ }
}
}
@@ -136,47 +125,42 @@ void AnimationBackend::stop(bool isAsync) {
}
void AnimationBackend::commitUpdates(
- std::unordered_map& surfaceUpdates) {
- for (auto& surfaceEntry : surfaceUpdates) {
- const auto& surfaceId = surfaceEntry.first;
- const auto& surfaceFamilies = surfaceEntry.second.families;
- auto& updates = surfaceEntry.second.propsMap;
- uiManager_->getShadowTreeRegistry().visit(
- surfaceId, [&surfaceFamilies, &updates](const ShadowTree& shadowTree) {
- shadowTree.commit(
- [&surfaceFamilies,
- &updates](const RootShadowNode& oldRootShadowNode) {
- return std::static_pointer_cast(
- oldRootShadowNode.cloneMultiple(
- surfaceFamilies,
- [&surfaceFamilies, &updates](
- const ShadowNode& shadowNode,
- const ShadowNodeFragment& fragment) {
- auto newProps =
- ShadowNodeFragment::propsPlaceholder();
- if (surfaceFamilies.contains(
- &shadowNode.getFamily())) {
- auto& animatedProps =
- updates.at(shadowNode.getTag());
- newProps = cloneProps(animatedProps, shadowNode);
- }
- return shadowNode.clone(
- {.props = newProps,
- .children = fragment.children,
- .state = shadowNode.getState(),
- .runtimeShadowNodeReference = false});
- }));
- },
- {.mountSynchronously = true});
- });
- }
+ SurfaceId surfaceId,
+ SurfaceUpdates& surfaceUpdates) {
+ auto& surfaceFamilies = surfaceUpdates.families;
+ auto& updates = surfaceUpdates.propsMap;
+ uiManager_->getShadowTreeRegistry().visit(
+ surfaceId, [&surfaceFamilies, &updates](const ShadowTree& shadowTree) {
+ shadowTree.commit(
+ [&surfaceFamilies,
+ &updates](const RootShadowNode& oldRootShadowNode) {
+ return std::static_pointer_cast(
+ oldRootShadowNode.cloneMultiple(
+ surfaceFamilies,
+ [&surfaceFamilies, &updates](
+ const ShadowNode& shadowNode,
+ const ShadowNodeFragment& fragment) {
+ auto newProps = ShadowNodeFragment::propsPlaceholder();
+ if (surfaceFamilies.contains(&shadowNode.getFamily())) {
+ auto& animatedProps = updates.at(shadowNode.getTag());
+ newProps = cloneProps(animatedProps, shadowNode);
+ }
+ return shadowNode.clone(
+ {.props = newProps,
+ .children = fragment.children,
+ .state = shadowNode.getState(),
+ .runtimeShadowNodeReference = false});
+ }));
+ },
+ {.mountSynchronously = true});
+ });
}
void AnimationBackend::synchronouslyUpdateProps(
const std::unordered_map& updates) {
for (auto& [tag, animatedProps] : updates) {
- // TODO: We shouldn't repack it into dynamic, but for that a rewrite of
- // directManipulationCallback_ is needed
+ // TODO: We shouldn't repack it into dynamic, but for that a rewrite
+ // of directManipulationCallback_ is needed
auto dyn = animationbackend::packAnimatedProps(animatedProps);
directManipulationCallback_(tag, std::move(dyn));
}
diff --git a/packages/react-native/ReactCommon/react/renderer/animationbackend/AnimationBackend.h b/packages/react-native/ReactCommon/react/renderer/animationbackend/AnimationBackend.h
index d8f7e3a326d9f1..7e0bd9bbe81fb8 100644
--- a/packages/react-native/ReactCommon/react/renderer/animationbackend/AnimationBackend.h
+++ b/packages/react-native/ReactCommon/react/renderer/animationbackend/AnimationBackend.h
@@ -36,9 +36,12 @@ struct AnimationMutation {
Tag tag;
std::shared_ptr family;
AnimatedProps props;
+ bool hasLayoutUpdates{false};
};
-using AnimationMutations = std::vector;
+struct AnimationMutations {
+ std::vector batch;
+};
class AnimationBackend : public UIManagerAnimationBackend {
public:
@@ -63,7 +66,7 @@ class AnimationBackend : public UIManagerAnimationBackend {
DirectManipulationCallback &&directManipulationCallback,
FabricCommitCallback &&fabricCommitCallback,
UIManager *uiManager);
- void commitUpdates(std::unordered_map &surfaceUpdates);
+ void commitUpdates(SurfaceId surfaceId, SurfaceUpdates &surfaceUpdates);
void synchronouslyUpdateProps(const std::unordered_map &updates);
void clearRegistry(SurfaceId surfaceId) override;
diff --git a/packages/react-native/ReactCommon/react/renderer/animationbackend/AnimationBackendCommitHook.cpp b/packages/react-native/ReactCommon/react/renderer/animationbackend/AnimationBackendCommitHook.cpp
index 5cb990fb68ade4..6d359ea8c1c38e 100644
--- a/packages/react-native/ReactCommon/react/renderer/animationbackend/AnimationBackendCommitHook.cpp
+++ b/packages/react-native/ReactCommon/react/renderer/animationbackend/AnimationBackendCommitHook.cpp
@@ -43,13 +43,19 @@ RootShadowNode::Unshared AnimationBackendCommitHook::shadowTreeWillCommit(
if (surfaceFamilies.contains(&shadowNode.getFamily()) &&
updates.contains(shadowNode.getTag())) {
auto& snapshot = updates.at(shadowNode.getTag());
- if (!snapshot->propNames.empty()) {
+ if (!snapshot->propNames.empty() || snapshot->rawProps) {
PropsParserContext propsParserContext{
shadowNode.getSurfaceId(),
*shadowNode.getContextContainer()};
-
- newProps = shadowNode.getComponentDescriptor().cloneProps(
- propsParserContext, shadowNode.getProps(), {});
+ if (snapshot->rawProps) {
+ newProps = shadowNode.getComponentDescriptor().cloneProps(
+ propsParserContext,
+ shadowNode.getProps(),
+ RawProps(*snapshot->rawProps));
+ } else {
+ newProps = shadowNode.getComponentDescriptor().cloneProps(
+ propsParserContext, shadowNode.getProps(), {});
+ }
viewProps = std::const_pointer_cast(
std::static_pointer_cast(newProps));
}