RN: Enable scheduleAnimatedEndCallbackInMicrotask (#47503)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47503

Enables the `scheduleAnimatedEndCallbackInMicrotask` feature flag that was introduced in https://github.com/facebook/react-native/pull/46714.

Changelog:
[General][Changed] - Callbacks passed to `animation.start(<callback>)` will be scheduled for execution in a microtask. Previously, there were certain scenarios in which the callback could be synchronously executed by `start`.

Reviewed By: javache

Differential Revision: D65645981

fbshipit-source-id: ac159208b7c1df60549baa52704bb0e704da0acf
This commit is contained in:
Tim Yung
2024-11-08 10:22:12 -08:00
committed by Facebook GitHub Bot
parent 105f5f6000
commit 090501d26d
4 changed files with 9 additions and 23 deletions
@@ -121,10 +121,12 @@ describe('Animated', () => {
await unmount(root);
expect(callback).not.toBeCalled();
await jest.runOnlyPendingTimersAsync();
expect(callback).toBeCalledWith({finished: false});
});
it('triggers callback when spring is at rest', () => {
it('triggers callback when spring is at rest', async () => {
const anim = new Animated.Value(0);
const callback = jest.fn();
Animated.spring(anim, {
@@ -132,7 +134,10 @@ describe('Animated', () => {
velocity: 0,
useNativeDriver: false,
}).start(callback);
expect(callback).toBeCalled();
expect(callback).not.toBeCalled();
await jest.runOnlyPendingTimersAsync();
expect(callback).toBeCalledWith({finished: true});
});
it('send toValue when a critically damped spring stops', () => {
@@ -165,11 +165,7 @@ export default class Animation {
const callback = this.#onEnd;
if (callback != null) {
this.#onEnd = null;
if (ReactNativeFeatureFlags.scheduleAnimatedEndCallbackInMicrotask()) {
queueMicrotask(() => callback(result));
} else {
callback(result);
}
queueMicrotask(() => callback(result));
}
}
}
@@ -560,15 +560,6 @@ const definitions: FeatureFlagDefinitions = {
purpose: 'release',
},
},
scheduleAnimatedEndCallbackInMicrotask: {
defaultValue: false,
metadata: {
dateAdded: '2024-09-27',
description:
'Changes the completion callback supplied via `Animation#start` to be scheduled in a microtask instead of synchronously executed.',
purpose: 'experimentation',
},
},
shouldSkipStateUpdatesForLoopingAnimations: {
defaultValue: false,
metadata: {
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<650ba11a0ac49b9779c6c98f57f7369f>>
* @generated SignedSource<<716c4507093099c254b57d744366bd05>>
* @flow strict
*/
@@ -37,7 +37,6 @@ export type ReactNativeFeatureFlagsJsOnly = {
enableAnimatedPropsMemo: Getter<boolean>,
enableOptimisedVirtualizedCells: Getter<boolean>,
isLayoutAnimationEnabled: Getter<boolean>,
scheduleAnimatedEndCallbackInMicrotask: Getter<boolean>,
shouldSkipStateUpdatesForLoopingAnimations: Getter<boolean>,
shouldUseAnimatedObjectForTransform: Getter<boolean>,
shouldUseRemoveClippedSubviewsAsDefaultOnIOS: Getter<boolean>,
@@ -154,11 +153,6 @@ export const enableOptimisedVirtualizedCells: Getter<boolean> = createJavaScript
*/
export const isLayoutAnimationEnabled: Getter<boolean> = createJavaScriptFlagGetter('isLayoutAnimationEnabled', true);
/**
* Changes the completion callback supplied via `Animation#start` to be scheduled in a microtask instead of synchronously executed.
*/
export const scheduleAnimatedEndCallbackInMicrotask: Getter<boolean> = createJavaScriptFlagGetter('scheduleAnimatedEndCallbackInMicrotask', false);
/**
* If the animation is within Animated.loop, we do not send state updates to React.
*/