From fe8f0fb09fa8761549b14414ff7baafd723a1e15 Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Tue, 11 Oct 2022 03:35:58 -0700 Subject: [PATCH] Apply Animated initialProps handling to Fabric only (#34927) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/34927 The changes made in D36902220 (https://github.com/facebook/react-native/commit/a04195167bbd8f27c6141c0239a61a345cac5a88) and D36958882 (https://github.com/facebook/react-native/commit/d8c25ca1b62df2b93f70bbb1f7b379643ab9ccd4) attempted to reduce flickering and consistency issues when using Animated. In the old renderer, we explicitly reset all animated props, and wait for the subsequent React commit to set the props to the right state, but if `initialProps` are used, the React reconciliation may not be able to identify the prop-update is required and will leave out the value. This behaviour is different in the new renderer, where we do not explicitly `restoreDefaultValues` on detaching the animated node, and instead rely on the latest state being correct(?). Changelog: [General][Fixed] Stop styles from being reset when detaching Animated.Values in old renderer Fixes #34665 Reviewed By: rshest Differential Revision: D40194072 fbshipit-source-id: 1b3fb1d1f4a39036a501a8a21e57002035dd5659 # Conflicts: # Libraries/Animated/createAnimatedComponent.js --- Libraries/Animated/createAnimatedComponent.js | 19 +++++++++++++------ Libraries/Animated/nodes/AnimatedProps.js | 4 +--- .../react/animated/NativeAnimatedModule.java | 12 ++++-------- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/Libraries/Animated/createAnimatedComponent.js b/Libraries/Animated/createAnimatedComponent.js index c9dbe808ed7..f4abdff1dc7 100644 --- a/Libraries/Animated/createAnimatedComponent.js +++ b/Libraries/Animated/createAnimatedComponent.js @@ -200,18 +200,25 @@ function createAnimatedComponent( }, }); - render() { + render(): React.Node { + // When rendering in Fabric and an AnimatedValue is used, we keep track of + // the initial value of that Value, to avoid additional prop updates when + // this component re-renders + const initialPropsIfFabric = this._isFabric() + ? this._initialAnimatedProps + : null; + const animatedProps = - this._propsAnimated.__getValue(this._initialAnimatedProps) || {}; + this._propsAnimated.__getValue(initialPropsIfFabric) || {}; + if (!this._initialAnimatedProps) { + this._initialAnimatedProps = animatedProps; + } + const {style = {}, ...props} = animatedProps; const {style: passthruStyle = {}, ...passthruProps} = this.props.passthroughAnimatedPropExplicitValues || {}; const mergedStyle = {...style, ...passthruStyle}; - if (!this._initialAnimatedProps) { - this._initialAnimatedProps = animatedProps; - } - // Force `collapsable` to be false so that native view is not flattened. // Flattened views cannot be accurately referenced by a native driver. return ( diff --git a/Libraries/Animated/nodes/AnimatedProps.js b/Libraries/Animated/nodes/AnimatedProps.js index d4ed70da8d6..c1aae27889f 100644 --- a/Libraries/Animated/nodes/AnimatedProps.js +++ b/Libraries/Animated/nodes/AnimatedProps.js @@ -46,9 +46,7 @@ class AnimatedProps extends AnimatedNode { // as they may not be up to date, so we use the initial value to ensure that values of // native animated nodes do not impact rerenders. if (value instanceof AnimatedStyle) { - props[key] = value.__getValue( - initialProps ? initialProps.style : null, - ); + props[key] = value.__getValue(initialProps?.style); } else if (!initialProps || !value.__isNative) { props[key] = value.__getValue(); } else if (initialProps.hasOwnProperty(key)) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java index f3b7e4e4040..bcbb2b082bd 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java @@ -871,7 +871,7 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec if (ANIMATED_MODULE_DEBUG) { FLog.d( NAME, - "queue: disconnectAnimatedNodeFromView: " + animatedNodeTag + " viewTag: " + viewTag); + "queue disconnectAnimatedNodeFromView: " + animatedNodeTag + " viewTag: " + viewTag); } decrementInFlightAnimationsForViewTag(viewTag); @@ -883,7 +883,7 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec if (ANIMATED_MODULE_DEBUG) { FLog.d( NAME, - "execute: disconnectAnimatedNodeFromView: " + "execute disconnectAnimatedNodeFromView: " + animatedNodeTag + " viewTag: " + viewTag); @@ -897,8 +897,7 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec public void restoreDefaultValues(final double animatedNodeTagDouble) { final int animatedNodeTag = (int) animatedNodeTagDouble; if (ANIMATED_MODULE_DEBUG) { - FLog.d( - NAME, "queue restoreDefaultValues: disconnectAnimatedNodeFromView: " + animatedNodeTag); + FLog.d(NAME, "queue restoreDefaultValues: " + animatedNodeTag); } addPreOperation( @@ -906,10 +905,7 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec @Override public void execute(NativeAnimatedNodesManager animatedNodesManager) { if (ANIMATED_MODULE_DEBUG) { - FLog.d( - NAME, - "execute restoreDefaultValues: disconnectAnimatedNodeFromView: " - + animatedNodeTag); + FLog.d(NAME, "execute restoreDefaultValues: " + animatedNodeTag); } animatedNodesManager.restoreDefaultValues(animatedNodeTag); }