From fe53cae954b37528eeaa1258ac0060c4298473bb Mon Sep 17 00:00:00 2001 From: Eric Rozell Date: Fri, 10 Dec 2021 08:06:15 -0800 Subject: [PATCH] Deduct offset from `getValue` result when detaching Summary: The NativeAnimated `getValue` API returns `value + offset`: Android: iOS: https://github.com/facebook/react-native/blob/main/Libraries/NativeAnimation/Nodes/RCTValueAnimatedNode.m#L44 Android: https://github.com/facebook/react-native/blob/main/ReactAndroid/src/main/java/com/facebook/react/animated/ValueAnimatedNode.java#L36 When we store the value after detaching the NativeAnimated node, it stores the result of the NativeAnimated `getValue` call to the `_value` property, so if we call `__getValue` at some later point on the `AnimatedValue`, we will count the offset twice. This change deducts the offset value from the result returned from `getValue` when storing the latest value. Changelog: [General][Fixed] - AnimatedValue.__detach should store getValue result with offset deducted Reviewed By: yungsters Differential Revision: D32987003 fbshipit-source-id: 488d1fe512f886c7a9de1e5a4de8f19441ebd81e --- .../Animated/__tests__/AnimatedNative-test.js | 22 +++++++++++++++++++ Libraries/Animated/nodes/AnimatedValue.js | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Libraries/Animated/__tests__/AnimatedNative-test.js b/Libraries/Animated/__tests__/AnimatedNative-test.js index 9ce09a72d6ab6b..eade44048d873b 100644 --- a/Libraries/Animated/__tests__/AnimatedNative-test.js +++ b/Libraries/Animated/__tests__/AnimatedNative-test.js @@ -134,6 +134,28 @@ describe('Native Animated', () => { expect(opacity.__getValue()).toBe(1); }); + it('should deduct offset when saving value on unmount', () => { + NativeAnimatedModule.getValue = jest.fn((tag, saveCallback) => { + // Assume current raw value of value node is 0.5, the NativeAnimated + // getValue API returns the sum of raw value and offset, so return 1. + saveCallback(1); + }); + const opacity = new Animated.Value(0); + opacity.setOffset(0.5); + opacity.__makeNative(); + + const root = TestRenderer.create(); + const tag = opacity.__getNativeTag(); + + root.unmount(); + + expect(NativeAnimatedModule.getValue).toBeCalledWith( + tag, + expect.any(Function), + ); + expect(opacity.__getValue()).toBe(1); + }); + it('should extract offset', () => { const opacity = new Animated.Value(0); opacity.__makeNative(); diff --git a/Libraries/Animated/nodes/AnimatedValue.js b/Libraries/Animated/nodes/AnimatedValue.js index d3361b86cfbfbe..e0f31f2a4fc4c2 100644 --- a/Libraries/Animated/nodes/AnimatedValue.js +++ b/Libraries/Animated/nodes/AnimatedValue.js @@ -100,7 +100,7 @@ class AnimatedValue extends AnimatedWithChildren { __detach() { if (this.__isNative) { NativeAnimatedAPI.getValue(this.__getNativeTag(), value => { - this._value = value; + this._value = value - this._offset; }); } this.stopAnimation();