Skip to content

Commit 4b8e904

Browse files
authored
Update AnimatedColor-test.js
<!-- Thanks for submitting a pull request! We appreciate you spending the time to work on these changes. Please provide enough information so that others can review your pull request. The three fields below are mandatory. --> ## Summary: Fixed an issue in `AnimatedColor.js` where `_listenerCount` could become negative during complex unmount/detach phases. When `__detach()` is invoked on `AnimatedColor`, it triggers `removeAllListeners()` on its underlying channel nodes (r, g, b, a), resetting their counts to 0. Subsequent stale infrastructure cleanups safely invoke `removeListener()`, which blindly decremented the counter to -1, bypassing the `=== 0` check and permanently leaking native subscriptions. This PR implements an overridden `removeListener` and `addListener` routine in `AnimatedColor` (mirroring the robust pattern in `AnimatedValueXY`) to act as a defensive shield and guarantee stable listener lifecycles. ## Changelog: [General] [Fixed] - Prevent negative listener count and native subscription memory leaks in AnimatedColor during detach cascades ## Test Plan: Added a comprehensive regression test suite in `packages/react-native/Libraries/Animated/tests/AnimatedColor-test.js` covering: - Verifying `_listenerCount` does not drop into negative values after a `__detach()` and subsequent `removeListener()` execution. - Testing `removeListener` safely acts as a no-op when called after `removeAllListeners()`. - Ensuring native driver subscriptions are properly initiated and systematically torn down without memory leaks during complex component unmount/re-attach lifecycles. Tested locally by running: `yarn jest AnimatedColor-test`
1 parent 94a87fc commit 4b8e904

1 file changed

Lines changed: 2 additions & 2 deletions

File tree

packages/react-native/Libraries/Animated/__tests__/AnimatedColor-test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ describe('AnimatedColor', () => {
7272
// 2. __detach() → calls removeAllListeners() on r/g/b/a
7373
// → r/g/b/a _listenerCount = 0
7474
// 3. removeListener(id) → calls r.removeListener() etc.
75-
// → WITHOUT fix: r/g/b/a _listenerCount = -1
76-
// → WITH fix: early return, stays at 0
75+
// → WITHOUT fix: r/g/b/a _listenerCount = -1
76+
// → WITH fix: early return, stays at 0
7777
const color = new AnimatedColor({r: 0, g: 0, b: 0, a: 1});
7878
color.__attach();
7979

0 commit comments

Comments
 (0)