Repository navigation
Conversation
Contributor
|
This pull request was exported from Phabricator. Differential Revision: D67884973 |
Contributor
|
This pull request was exported from Phabricator. Differential Revision: D67884973 |
yungsters
force-pushed
the
export-D67884973
branch
from
January 7, 2025 08:11
f1d023d to
5888c3d
Compare
Summary: While refactoring `Animated`, I noticed that many subclasses of `AnimatedNode` override `__attach` without invoking the superclass method, even though we do this for `__detach`. In order to minimize surprise (e.g. if someone were to add logic into `AnimatedNode.prototype.__attach`), this diff updates all method overrides to invoke `super.__attach()`. Changelog: [Internal] Differential Revision: D67884975
Summary: Pull Request resolved: react#48514 Currently, `AnimatedNode` implements logic to start listening to updates on the current native node if a listener is added. However, the `startListeningToAnimatedNodeValue` native module method only supports native tags for instances of `AnimatedValue`, which is a subclass of `AnimatedNode`. In fact… * On Android, [`startListeningToAnimatedNodeValue`](https://fburl.com/code/bdsl4sro) throws if the node is not an instance of `ValueAnimatedNode`. * On iOS, [`startListeningToAnimatedNodeValue`](https://fburl.com/code/hlpk1rzk) does nothing if node is not an instance of `RCTValueAnimatedNode`. As such, this refactors `AnimatedNode` to never manage this subscription for native nodes. Instead, the logic is moved into the `AnimatedValue` subclass, ensuring that we never accidentally try to `startListeningToAnimatedNodeValue` with non-`AnimatedValue` native tags. Changelog: [Internal] Reviewed By: javache Differential Revision: D67884973
Contributor
|
This pull request was exported from Phabricator. Differential Revision: D67884973 |
yungsters
force-pushed
the
export-D67884973
branch
from
January 7, 2025 16:00
5888c3d to
014169b
Compare
Contributor
|
This pull request has been merged in 38c46fe. |
8 tasks done
meta-codesync Bot
pushed a commit
that referenced
this pull request
Sep 2, 2026
Summary: Fixes #49719. `addListener` stopped firing on any `AnimatedNode` *derived* from an `Animated.Value` — `Animated.add`/`subtract`/`multiply`/`divide`/`modulo`/`diffClamp` and `.interpolate()` — for natively driven animations. It worked in 0.77 and regressed in 0.78. The issue has since been reported for both `Animated.add` and `.interpolate()`, on both architectures, and the only workaround is to listen to the source value and recompute the derived value in JS — which observes intermediate values that never reach the screen. There are two independent causes. ### 1. JS: derived nodes never subscribe to native updates Before 38c46fe ("Animated: Lower `onAnimatedValueUpdate` to `AnimatedValue`", #48514), `AnimatedNode.addListener` called `startListeningToAnimatedNodeValue` for any node that had been made native. That commit moved the logic down into `AnimatedValue`, on the premise that: > the `startListeningToAnimatedNodeValue` native module method only supports native tags for instances of `AnimatedValue` […] On Android, `startListeningToAnimatedNodeValue` throws if the node is not an instance of `ValueAnimatedNode`. On iOS, it does nothing if node is not an instance of `RCTValueAnimatedNode`. That holds for props/style/transform/object/tracking/color nodes, but not for the operator and interpolation nodes, which *are* value nodes natively: - **Android** — `AdditionAnimatedNode`, `SubtractionAnimatedNode`, `MultiplicationAnimatedNode`, `DivisionAnimatedNode`, `ModulusAnimatedNode`, `DiffClampAnimatedNode` and `InterpolationAnimatedNode` all extend `ValueAnimatedNode`, and `NativeAnimatedNodesManager` checks `node !is ValueAnimatedNode`. - **iOS** — the corresponding `RCT*AnimatedNode` classes all inherit `RCTValueAnimatedNode`, and the manager checks `isKindOfClass:[RCTValueAnimatedNode class]`. So the subscription was dropped for a set of nodes that natively support it. This restores it on `AnimatedNode`, gated on a new `__isNativeValueNode` flag that is `true` only for nodes backed by a native value node. That keeps the guarantee #48514 was after — never call `startListeningToAnimatedNodeValue` with a non-value tag — but states it explicitly instead of leaving it implicit in the class hierarchy. `AnimatedValue` now inherits that machinery rather than duplicating it. `AnimatedNode.__detach` also drops the subscription before `dropAnimatedNode`, so it can never outlive the tag it observes. ### 2. C++: `startListeningToAnimatedNodeValue` rejects derived value nodes Unlike Android and iOS, the C++ backend used by the New Architecture compares the node's *exact* type tag instead of testing for a `ValueAnimatedNode` subclass: ```c++ iter->second->type() == AnimatedNodeType::Value ``` so an addition or interpolation node was rejected with `"does not exist, or is not a 'value' node"`, even though `static_cast<ValueAnimatedNode*>` would have been valid. Replaced with an exhaustive `isValueNodeType` predicate, so every node type whose C++ class derives from `ValueAnimatedNode` (including `Round`) is accepted and the non-value ones are still rejected. `AnimatedNode.__onAnimatedValueUpdateReceived` had to accept a missing `offset` as well: the C++ backend emits `onAnimatedValueUpdate` without one, which would otherwise produce `NaN` (`value + undefined`). ## Changelog: [GENERAL] [FIXED] - `addListener` fires again for natively driven `Animated` values derived with `add`/`subtract`/`multiply`/`divide`/`modulo`/`diffClamp`/`interpolate` Pull Request resolved: #58037 Test Plan: ### New tests **`Libraries/Animated/__tests__/AnimatedComposition-itest.js`** — renders a derived node bound to `translateX`, attaches a listener to the *derived* node before it is made native, runs a `timing` animation on the source value, and asserts the listener observed the derived value; then asserts `removeListener` stops the updates. Parameterised over the five operators plus `interpolate`, and over both drivers. **`ReactCommon/react/renderer/animated/tests/AnimatedNodeTests.cpp`** — `StartListeningToDerivedValueNode` asserts the C++ backend delivers updates for an `addition` node and stops on `stopListeningToAnimatedNodeValue`. `StartListeningToNonValueNodeIsIgnored` asserts registering on a `transform` node is still a no-op. ### Results ``` $ yarn fantom packages/react-native/Libraries/Animated/__tests__/AnimatedComposition-itest.js addListener on derived value nodes ✓ Animated.add notifies its listeners on the JS driver ✓ Animated.subtract notifies its listeners on the JS driver ✓ Animated.multiply notifies its listeners on the JS driver ✓ Animated.divide notifies its listeners on the JS driver ✓ Animated.modulo notifies its listeners on the JS driver ✓ interpolate notifies its listeners on the JS driver ✓ Animated.add notifies its listeners on the native driver ✓ Animated.subtract notifies its listeners on the native driver ✓ Animated.multiply notifies its listeners on the native driver ✓ Animated.divide notifies its listeners on the native driver ✓ Animated.modulo notifies its listeners on the native driver ✓ interpolate notifies its listeners on the native driver Tests: 26 passed, 26 total ``` Reverting only the fix (keeping the new test) fails exactly the six `native driver` cases, which is the reported bug; the `JS driver` cases were never broken: ``` ✕ Animated.add notifies its listeners on the native driver Expected 0 to be greater than or equal to 0 > 469 | expect(values.length).toBeGreaterThan(0); … Tests: 6 failed, 20 passed, 26 total ``` No regressions in the rest of the Animated suite: ``` $ yarn fantom packages/react-native/Libraries/Animated/__tests__/ Test Suites: 2 skipped, 16 passed, 16 of 18 total Tests: 3 skipped, 297 passed, 300 total $ yarn jest packages/react-native/Libraries/Animated Test Suites: 3 passed, 3 total Tests: 66 passed, 66 total $ yarn flow-check Found 0 errors $ yarn lint # changed files (no output) ``` `yarn build-types` regenerated `ReactNativeApi.d.ts`; the only substantive change is that `AnimatedValue`'s `removeListener`/`removeAllListeners` are now inherited from `AnimatedNode` rather than redeclared. `addListener` keeps its narrower `ValueListenerCallback` signature. Correction to an earlier revision of this description: the C++ tests were not run locally, and they are not covered by the public CI either. `react/renderer/animated/tests` is excluded from the iOS build (`React-Fabric.podspec`: `ss.exclude_files = "react/renderer/animated/tests"`) and is not in the Android CMake glob (`react/renderer/animated/CMakeLists.txt` globs `*.cpp drivers/*.cpp event_drivers/*.cpp internal/*.cpp nodes/*.cpp`), so they build only in the internal build reached at import time. What is verified here: `NativeAnimatedNodesManager.cpp` compiles clean under `-Wall -Werror -Wpedantic` as part of the Fantom tester build, and the JS-side changes are covered by the Fantom and Jest runs above. ### Notes For a colour `interpolate()` on the native driver the listener receives the interpolated colour as a number rather than a string, because the value is computed natively. That matches pre-0.78 behaviour and is out of scope here. Reviewed By: christophpurrer, cipolleschi Differential Revision: D117209945 Pulled By: zeyap fbshipit-source-id: b50657a7b2d25e10e980b43cb1e9e1f1db5f3906
shashikant-panchal
pushed a commit
to shashikant-panchal/react-native
that referenced
this pull request
Sep 10, 2026
) Summary: Fixes react#49719. `addListener` stopped firing on any `AnimatedNode` *derived* from an `Animated.Value` — `Animated.add`/`subtract`/`multiply`/`divide`/`modulo`/`diffClamp` and `.interpolate()` — for natively driven animations. It worked in 0.77 and regressed in 0.78. The issue has since been reported for both `Animated.add` and `.interpolate()`, on both architectures, and the only workaround is to listen to the source value and recompute the derived value in JS — which observes intermediate values that never reach the screen. There are two independent causes. ### 1. JS: derived nodes never subscribe to native updates Before 38c46fe ("Animated: Lower `onAnimatedValueUpdate` to `AnimatedValue`", react#48514), `AnimatedNode.addListener` called `startListeningToAnimatedNodeValue` for any node that had been made native. That commit moved the logic down into `AnimatedValue`, on the premise that: > the `startListeningToAnimatedNodeValue` native module method only supports native tags for instances of `AnimatedValue` […] On Android, `startListeningToAnimatedNodeValue` throws if the node is not an instance of `ValueAnimatedNode`. On iOS, it does nothing if node is not an instance of `RCTValueAnimatedNode`. That holds for props/style/transform/object/tracking/color nodes, but not for the operator and interpolation nodes, which *are* value nodes natively: - **Android** — `AdditionAnimatedNode`, `SubtractionAnimatedNode`, `MultiplicationAnimatedNode`, `DivisionAnimatedNode`, `ModulusAnimatedNode`, `DiffClampAnimatedNode` and `InterpolationAnimatedNode` all extend `ValueAnimatedNode`, and `NativeAnimatedNodesManager` checks `node !is ValueAnimatedNode`. - **iOS** — the corresponding `RCT*AnimatedNode` classes all inherit `RCTValueAnimatedNode`, and the manager checks `isKindOfClass:[RCTValueAnimatedNode class]`. So the subscription was dropped for a set of nodes that natively support it. This restores it on `AnimatedNode`, gated on a new `__isNativeValueNode` flag that is `true` only for nodes backed by a native value node. That keeps the guarantee react#48514 was after — never call `startListeningToAnimatedNodeValue` with a non-value tag — but states it explicitly instead of leaving it implicit in the class hierarchy. `AnimatedValue` now inherits that machinery rather than duplicating it. `AnimatedNode.__detach` also drops the subscription before `dropAnimatedNode`, so it can never outlive the tag it observes. ### 2. C++: `startListeningToAnimatedNodeValue` rejects derived value nodes Unlike Android and iOS, the C++ backend used by the New Architecture compares the node's *exact* type tag instead of testing for a `ValueAnimatedNode` subclass: ```c++ iter->second->type() == AnimatedNodeType::Value ``` so an addition or interpolation node was rejected with `"does not exist, or is not a 'value' node"`, even though `static_cast<ValueAnimatedNode*>` would have been valid. Replaced with an exhaustive `isValueNodeType` predicate, so every node type whose C++ class derives from `ValueAnimatedNode` (including `Round`) is accepted and the non-value ones are still rejected. `AnimatedNode.__onAnimatedValueUpdateReceived` had to accept a missing `offset` as well: the C++ backend emits `onAnimatedValueUpdate` without one, which would otherwise produce `NaN` (`value + undefined`). ## Changelog: [GENERAL] [FIXED] - `addListener` fires again for natively driven `Animated` values derived with `add`/`subtract`/`multiply`/`divide`/`modulo`/`diffClamp`/`interpolate` Pull Request resolved: react#58037 Test Plan: ### New tests **`Libraries/Animated/__tests__/AnimatedComposition-itest.js`** — renders a derived node bound to `translateX`, attaches a listener to the *derived* node before it is made native, runs a `timing` animation on the source value, and asserts the listener observed the derived value; then asserts `removeListener` stops the updates. Parameterised over the five operators plus `interpolate`, and over both drivers. **`ReactCommon/react/renderer/animated/tests/AnimatedNodeTests.cpp`** — `StartListeningToDerivedValueNode` asserts the C++ backend delivers updates for an `addition` node and stops on `stopListeningToAnimatedNodeValue`. `StartListeningToNonValueNodeIsIgnored` asserts registering on a `transform` node is still a no-op. ### Results ``` $ yarn fantom packages/react-native/Libraries/Animated/__tests__/AnimatedComposition-itest.js addListener on derived value nodes ✓ Animated.add notifies its listeners on the JS driver ✓ Animated.subtract notifies its listeners on the JS driver ✓ Animated.multiply notifies its listeners on the JS driver ✓ Animated.divide notifies its listeners on the JS driver ✓ Animated.modulo notifies its listeners on the JS driver ✓ interpolate notifies its listeners on the JS driver ✓ Animated.add notifies its listeners on the native driver ✓ Animated.subtract notifies its listeners on the native driver ✓ Animated.multiply notifies its listeners on the native driver ✓ Animated.divide notifies its listeners on the native driver ✓ Animated.modulo notifies its listeners on the native driver ✓ interpolate notifies its listeners on the native driver Tests: 26 passed, 26 total ``` Reverting only the fix (keeping the new test) fails exactly the six `native driver` cases, which is the reported bug; the `JS driver` cases were never broken: ``` ✕ Animated.add notifies its listeners on the native driver Expected 0 to be greater than or equal to 0 > 469 | expect(values.length).toBeGreaterThan(0); … Tests: 6 failed, 20 passed, 26 total ``` No regressions in the rest of the Animated suite: ``` $ yarn fantom packages/react-native/Libraries/Animated/__tests__/ Test Suites: 2 skipped, 16 passed, 16 of 18 total Tests: 3 skipped, 297 passed, 300 total $ yarn jest packages/react-native/Libraries/Animated Test Suites: 3 passed, 3 total Tests: 66 passed, 66 total $ yarn flow-check Found 0 errors $ yarn lint # changed files (no output) ``` `yarn build-types` regenerated `ReactNativeApi.d.ts`; the only substantive change is that `AnimatedValue`'s `removeListener`/`removeAllListeners` are now inherited from `AnimatedNode` rather than redeclared. `addListener` keeps its narrower `ValueListenerCallback` signature. Correction to an earlier revision of this description: the C++ tests were not run locally, and they are not covered by the public CI either. `react/renderer/animated/tests` is excluded from the iOS build (`React-Fabric.podspec`: `ss.exclude_files = "react/renderer/animated/tests"`) and is not in the Android CMake glob (`react/renderer/animated/CMakeLists.txt` globs `*.cpp drivers/*.cpp event_drivers/*.cpp internal/*.cpp nodes/*.cpp`), so they build only in the internal build reached at import time. What is verified here: `NativeAnimatedNodesManager.cpp` compiles clean under `-Wall -Werror -Wpedantic` as part of the Fantom tester build, and the JS-side changes are covered by the Fantom and Jest runs above. ### Notes For a colour `interpolate()` on the native driver the listener receives the interpolated colour as a number rather than a string, because the value is computed natively. That matches pre-0.78 behaviour and is out of scope here. Reviewed By: christophpurrer, cipolleschi Differential Revision: D117209945 Pulled By: zeyap fbshipit-source-id: b50657a7b2d25e10e980b43cb1e9e1f1db5f3906
tvinhas
pushed a commit
to tvinhas/react-native-macos
that referenced
this pull request
Oct 21, 2026
) Summary: Fixes react#49719. `addListener` stopped firing on any `AnimatedNode` *derived* from an `Animated.Value` — `Animated.add`/`subtract`/`multiply`/`divide`/`modulo`/`diffClamp` and `.interpolate()` — for natively driven animations. It worked in 0.77 and regressed in 0.78. The issue has since been reported for both `Animated.add` and `.interpolate()`, on both architectures, and the only workaround is to listen to the source value and recompute the derived value in JS — which observes intermediate values that never reach the screen. There are two independent causes. ### 1. JS: derived nodes never subscribe to native updates Before 38c46fe ("Animated: Lower `onAnimatedValueUpdate` to `AnimatedValue`", react#48514), `AnimatedNode.addListener` called `startListeningToAnimatedNodeValue` for any node that had been made native. That commit moved the logic down into `AnimatedValue`, on the premise that: > the `startListeningToAnimatedNodeValue` native module method only supports native tags for instances of `AnimatedValue` […] On Android, `startListeningToAnimatedNodeValue` throws if the node is not an instance of `ValueAnimatedNode`. On iOS, it does nothing if node is not an instance of `RCTValueAnimatedNode`. That holds for props/style/transform/object/tracking/color nodes, but not for the operator and interpolation nodes, which *are* value nodes natively: - **Android** — `AdditionAnimatedNode`, `SubtractionAnimatedNode`, `MultiplicationAnimatedNode`, `DivisionAnimatedNode`, `ModulusAnimatedNode`, `DiffClampAnimatedNode` and `InterpolationAnimatedNode` all extend `ValueAnimatedNode`, and `NativeAnimatedNodesManager` checks `node !is ValueAnimatedNode`. - **iOS** — the corresponding `RCT*AnimatedNode` classes all inherit `RCTValueAnimatedNode`, and the manager checks `isKindOfClass:[RCTValueAnimatedNode class]`. So the subscription was dropped for a set of nodes that natively support it. This restores it on `AnimatedNode`, gated on a new `__isNativeValueNode` flag that is `true` only for nodes backed by a native value node. That keeps the guarantee react#48514 was after — never call `startListeningToAnimatedNodeValue` with a non-value tag — but states it explicitly instead of leaving it implicit in the class hierarchy. `AnimatedValue` now inherits that machinery rather than duplicating it. `AnimatedNode.__detach` also drops the subscription before `dropAnimatedNode`, so it can never outlive the tag it observes. ### 2. C++: `startListeningToAnimatedNodeValue` rejects derived value nodes Unlike Android and iOS, the C++ backend used by the New Architecture compares the node's *exact* type tag instead of testing for a `ValueAnimatedNode` subclass: ```c++ iter->second->type() == AnimatedNodeType::Value ``` so an addition or interpolation node was rejected with `"does not exist, or is not a 'value' node"`, even though `static_cast<ValueAnimatedNode*>` would have been valid. Replaced with an exhaustive `isValueNodeType` predicate, so every node type whose C++ class derives from `ValueAnimatedNode` (including `Round`) is accepted and the non-value ones are still rejected. `AnimatedNode.__onAnimatedValueUpdateReceived` had to accept a missing `offset` as well: the C++ backend emits `onAnimatedValueUpdate` without one, which would otherwise produce `NaN` (`value + undefined`). ## Changelog: [GENERAL] [FIXED] - `addListener` fires again for natively driven `Animated` values derived with `add`/`subtract`/`multiply`/`divide`/`modulo`/`diffClamp`/`interpolate` Pull Request resolved: react#58037 Test Plan: ### New tests **`Libraries/Animated/__tests__/AnimatedComposition-itest.js`** — renders a derived node bound to `translateX`, attaches a listener to the *derived* node before it is made native, runs a `timing` animation on the source value, and asserts the listener observed the derived value; then asserts `removeListener` stops the updates. Parameterised over the five operators plus `interpolate`, and over both drivers. **`ReactCommon/react/renderer/animated/tests/AnimatedNodeTests.cpp`** — `StartListeningToDerivedValueNode` asserts the C++ backend delivers updates for an `addition` node and stops on `stopListeningToAnimatedNodeValue`. `StartListeningToNonValueNodeIsIgnored` asserts registering on a `transform` node is still a no-op. ### Results ``` $ yarn fantom packages/react-native/Libraries/Animated/__tests__/AnimatedComposition-itest.js addListener on derived value nodes ✓ Animated.add notifies its listeners on the JS driver ✓ Animated.subtract notifies its listeners on the JS driver ✓ Animated.multiply notifies its listeners on the JS driver ✓ Animated.divide notifies its listeners on the JS driver ✓ Animated.modulo notifies its listeners on the JS driver ✓ interpolate notifies its listeners on the JS driver ✓ Animated.add notifies its listeners on the native driver ✓ Animated.subtract notifies its listeners on the native driver ✓ Animated.multiply notifies its listeners on the native driver ✓ Animated.divide notifies its listeners on the native driver ✓ Animated.modulo notifies its listeners on the native driver ✓ interpolate notifies its listeners on the native driver Tests: 26 passed, 26 total ``` Reverting only the fix (keeping the new test) fails exactly the six `native driver` cases, which is the reported bug; the `JS driver` cases were never broken: ``` ✕ Animated.add notifies its listeners on the native driver Expected 0 to be greater than or equal to 0 > 469 | expect(values.length).toBeGreaterThan(0); … Tests: 6 failed, 20 passed, 26 total ``` No regressions in the rest of the Animated suite: ``` $ yarn fantom packages/react-native/Libraries/Animated/__tests__/ Test Suites: 2 skipped, 16 passed, 16 of 18 total Tests: 3 skipped, 297 passed, 300 total $ yarn jest packages/react-native/Libraries/Animated Test Suites: 3 passed, 3 total Tests: 66 passed, 66 total $ yarn flow-check Found 0 errors $ yarn lint # changed files (no output) ``` `yarn build-types` regenerated `ReactNativeApi.d.ts`; the only substantive change is that `AnimatedValue`'s `removeListener`/`removeAllListeners` are now inherited from `AnimatedNode` rather than redeclared. `addListener` keeps its narrower `ValueListenerCallback` signature. Correction to an earlier revision of this description: the C++ tests were not run locally, and they are not covered by the public CI either. `react/renderer/animated/tests` is excluded from the iOS build (`React-Fabric.podspec`: `ss.exclude_files = "react/renderer/animated/tests"`) and is not in the Android CMake glob (`react/renderer/animated/CMakeLists.txt` globs `*.cpp drivers/*.cpp event_drivers/*.cpp internal/*.cpp nodes/*.cpp`), so they build only in the internal build reached at import time. What is verified here: `NativeAnimatedNodesManager.cpp` compiles clean under `-Wall -Werror -Wpedantic` as part of the Fantom tester build, and the JS-side changes are covered by the Fantom and Jest runs above. ### Notes For a colour `interpolate()` on the native driver the listener receives the interpolated colour as a number rather than a string, because the value is computed natively. That matches pre-0.78 behaviour and is out of scope here. Reviewed By: christophpurrer, cipolleschi Differential Revision: D117209945 Pulled By: zeyap fbshipit-source-id: b50657a7b2d25e10e980b43cb1e9e1f1db5f3906
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
Currently,
AnimatedNodeimplements logic to start listening to updates on the current native node if a listener is added.However, the
startListeningToAnimatedNodeValuenative module method only supports native tags for instances ofAnimatedValue, which is a subclass ofAnimatedNode. In fact…startListeningToAnimatedNodeValuethrows if the node is not an instance ofValueAnimatedNode.startListeningToAnimatedNodeValuedoes nothing if node is not an instance ofRCTValueAnimatedNode.As such, this refactors
AnimatedNodeto never manage this subscription for native nodes. Instead, the logic is moved into theAnimatedValuesubclass, ensuring that we never accidentally try tostartListeningToAnimatedNodeValuewith non-AnimatedValuenative tags.Changelog:
[Internal]
Differential Revision: D67884973