Skip to content

Commit 72158fc

Browse files
yungstersfacebook-github-bot
authored andcommitted
VirtualView: Create Activity Experiment (#53488)
Summary: Pull Request resolved: #53488 Creates a new feature flag to experiment with `Activity` in `VirtualView`. The feature flag enables the following treatments: - `no-activity` is the same as what we currently do — no `Activity` and we render `null` for hidden elements. - `activity-without-mode` wraps the children in `Activity` but does not set `mode` and still renders `null` for hidden elements. - `activity-with-hidden-mode` wraps the children in `Activity` and sets `mode="hidden"` and continues providing `children` (not `null`) for hidden elements. Changelog: [Internal] Reviewed By: rickhanlonii Differential Revision: D81149561 fbshipit-source-id: ea2c319139962de30836d80a2492d8147cbe82ba
1 parent 502325f commit 72158fc

File tree

4 files changed

+32
-3
lines changed

4 files changed

+32
-3
lines changed

packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,16 @@ const definitions: FeatureFlagDefinitions = {
914914
},
915915
ossReleaseStage: 'none',
916916
},
917+
virtualViewActivityBehavior: {
918+
defaultValue: 'no-activity',
919+
metadata: {
920+
dateAdded: '2025-08-27',
921+
description: 'Changes whether and how `VirtualView` uses `Activity`.',
922+
expectedReleaseValue: true,
923+
purpose: 'experimentation',
924+
},
925+
ossReleaseStage: 'none',
926+
},
917927
},
918928
};
919929

packages/react-native/src/private/components/virtualview/VirtualView.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@ import type {HostInstance} from '../../types/HostInstance';
1414
import type {NativeModeChangeEvent} from './VirtualViewNativeComponent';
1515

1616
import StyleSheet from '../../../../Libraries/StyleSheet/StyleSheet';
17+
import * as ReactNativeFeatureFlags from '../../featureflags/ReactNativeFeatureFlags';
1718
import VirtualViewExperimentalNativeComponent from './VirtualViewExperimentalNativeComponent';
1819
import VirtualViewNativeComponent from './VirtualViewNativeComponent';
1920
import nullthrows from 'nullthrows';
2021
import * as React from 'react';
21-
import {startTransition, useState} from 'react';
22+
// $FlowFixMe[missing-export]
23+
import {startTransition, unstable_Activity as Activity, useState} from 'react';
2224

2325
// @see VirtualViewNativeComponent
2426
export enum VirtualViewMode {
@@ -140,7 +142,17 @@ function createVirtualView(
140142
: style
141143
}
142144
onModeChange={handleModeChange}>
143-
{isHidden ? null : children}
145+
{
146+
match (ReactNativeFeatureFlags.virtualViewActivityBehavior()) {
147+
'activity-without-mode' =>
148+
<Activity>{isHidden ? null : children}</Activity>,
149+
'activity-with-hidden-mode' =>
150+
<Activity mode={isHidden ? 'hidden' : 'visible'}>
151+
{children}
152+
</Activity>,
153+
'no-activity' | _ => isHidden ? null : children,
154+
}
155+
}
144156
</NativeComponent>
145157
);
146158
}

packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<276b1579eef10e63c77752017b97985f>>
7+
* @generated SignedSource<<85a053d6a79240a7b4e181d3054ecfd3>>
88
* @flow strict
99
* @noformat
1010
*/
@@ -41,6 +41,7 @@ export type ReactNativeFeatureFlagsJsOnly = $ReadOnly<{
4141
shouldUseAnimatedObjectForTransform: Getter<boolean>,
4242
shouldUseRemoveClippedSubviewsAsDefaultOnIOS: Getter<boolean>,
4343
shouldUseSetNativePropsInFabric: Getter<boolean>,
44+
virtualViewActivityBehavior: Getter<string>,
4445
}>;
4546

4647
export type ReactNativeFeatureFlagsJsOnlyOverrides = OverridesFor<ReactNativeFeatureFlagsJsOnly>;
@@ -184,6 +185,11 @@ export const shouldUseRemoveClippedSubviewsAsDefaultOnIOS: Getter<boolean> = cre
184185
*/
185186
export const shouldUseSetNativePropsInFabric: Getter<boolean> = createJavaScriptFlagGetter('shouldUseSetNativePropsInFabric', true);
186187

188+
/**
189+
* Changes whether and how `VirtualView` uses `Activity`.
190+
*/
191+
export const virtualViewActivityBehavior: Getter<string> = createJavaScriptFlagGetter('virtualViewActivityBehavior', "no-activity");
192+
187193
/**
188194
* Common flag for testing. Do NOT modify.
189195
*/

packages/react-native/src/private/featureflags/ReactNativeFeatureFlagsBase.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export function createJavaScriptFlagGetter<
6161
configName,
6262
() => {
6363
accessedFeatureFlags.add(configName);
64+
// $FlowFixMe[incompatible-type] - `defaultValue` is not refined.
6465
return overrides?.[configName]?.(defaultValue);
6566
},
6667
defaultValue,

0 commit comments

Comments
 (0)