diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js
index a562ba4b6bf..9453c2539d7 100644
--- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js
+++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js
@@ -914,6 +914,16 @@ const definitions: FeatureFlagDefinitions = {
},
ossReleaseStage: 'none',
},
+ virtualViewActivityBehavior: {
+ defaultValue: 'no-activity',
+ metadata: {
+ dateAdded: '2025-08-27',
+ description: 'Changes whether and how `VirtualView` uses `Activity`.',
+ expectedReleaseValue: true,
+ purpose: 'experimentation',
+ },
+ ossReleaseStage: 'none',
+ },
},
};
diff --git a/packages/react-native/src/private/components/virtualview/VirtualView.js b/packages/react-native/src/private/components/virtualview/VirtualView.js
index ffeff6e43fe..d2330da72f0 100644
--- a/packages/react-native/src/private/components/virtualview/VirtualView.js
+++ b/packages/react-native/src/private/components/virtualview/VirtualView.js
@@ -14,11 +14,13 @@ import type {HostInstance} from '../../types/HostInstance';
import type {NativeModeChangeEvent} from './VirtualViewNativeComponent';
import StyleSheet from '../../../../Libraries/StyleSheet/StyleSheet';
+import * as ReactNativeFeatureFlags from '../../featureflags/ReactNativeFeatureFlags';
import VirtualViewExperimentalNativeComponent from './VirtualViewExperimentalNativeComponent';
import VirtualViewNativeComponent from './VirtualViewNativeComponent';
import nullthrows from 'nullthrows';
import * as React from 'react';
-import {startTransition, useState} from 'react';
+// $FlowFixMe[missing-export]
+import {startTransition, unstable_Activity as Activity, useState} from 'react';
// @see VirtualViewNativeComponent
export enum VirtualViewMode {
@@ -140,7 +142,17 @@ function createVirtualView(
: style
}
onModeChange={handleModeChange}>
- {isHidden ? null : children}
+ {
+ match (ReactNativeFeatureFlags.virtualViewActivityBehavior()) {
+ 'activity-without-mode' =>
+ {isHidden ? null : children},
+ 'activity-with-hidden-mode' =>
+
+ {children}
+ ,
+ 'no-activity' | _ => isHidden ? null : children,
+ }
+ }
);
}
diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js
index 065614781ea..929699d8c8c 100644
--- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js
+++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js
@@ -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<<276b1579eef10e63c77752017b97985f>>
+ * @generated SignedSource<<85a053d6a79240a7b4e181d3054ecfd3>>
* @flow strict
* @noformat
*/
@@ -41,6 +41,7 @@ export type ReactNativeFeatureFlagsJsOnly = $ReadOnly<{
shouldUseAnimatedObjectForTransform: Getter,
shouldUseRemoveClippedSubviewsAsDefaultOnIOS: Getter,
shouldUseSetNativePropsInFabric: Getter,
+ virtualViewActivityBehavior: Getter,
}>;
export type ReactNativeFeatureFlagsJsOnlyOverrides = OverridesFor;
@@ -184,6 +185,11 @@ export const shouldUseRemoveClippedSubviewsAsDefaultOnIOS: Getter = cre
*/
export const shouldUseSetNativePropsInFabric: Getter = createJavaScriptFlagGetter('shouldUseSetNativePropsInFabric', true);
+/**
+ * Changes whether and how `VirtualView` uses `Activity`.
+ */
+export const virtualViewActivityBehavior: Getter = createJavaScriptFlagGetter('virtualViewActivityBehavior', "no-activity");
+
/**
* Common flag for testing. Do NOT modify.
*/
diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlagsBase.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlagsBase.js
index 050b003a2ef..89b8e9042bc 100644
--- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlagsBase.js
+++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlagsBase.js
@@ -61,6 +61,7 @@ export function createJavaScriptFlagGetter<
configName,
() => {
accessedFeatureFlags.add(configName);
+ // $FlowFixMe[incompatible-type] - `defaultValue` is not refined.
return overrides?.[configName]?.(defaultValue);
},
defaultValue,