Skip to content

Commit 3f971d9

Browse files
yungstersmeta-codesync[bot]
authored andcommitted
Pressability: Setup Insertion Effect Experiment (#54292)
Summary: Pull Request resolved: #54292 Sets up a feature flag to experiment with using `useInsertionEffect` in `Pressability`, instead of `useEffect. Using `useInsertionEffect` enables `Pressability` to behave more predictability in component trees with `<Activity mode="hidden">` because the events are scheduled more similarly to platform controls (e.g. focus and blur events will still fire even when "hidden"). Changelog: [Internal] Reviewed By: javache Differential Revision: D85612742 fbshipit-source-id: c2faab25bfcf7f964521e680eb3c4132c1087ef4
1 parent c029032 commit 3f971d9

File tree

3 files changed

+32
-4
lines changed

3 files changed

+32
-4
lines changed

packages/react-native/Libraries/Pressability/usePressability.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,26 @@
88
* @format
99
*/
1010

11+
import * as ReactNativeFeatureFlags from '../../src/private/featureflags/ReactNativeFeatureFlags';
1112
import Pressability, {
1213
type EventHandlers,
1314
type PressabilityConfig,
1415
} from './Pressability';
15-
import {useEffect, useRef} from 'react';
16+
import {useEffect, useInsertionEffect, useRef} from 'react';
1617

1718
declare function usePressability(config: PressabilityConfig): EventHandlers;
1819
declare function usePressability(config: null | void): null | EventHandlers;
1920

21+
// Experiments with using `useInsertionEffect` instead of `useEffect`, which
22+
// changes whether `Pressability` is configured or reset when inm a hidden
23+
// Activity. With `useInsertionEffect`, `Pressability` behaves more like a
24+
// platform control (e.g. Pointer Events), especially with respect to events
25+
// like focus and blur.
26+
const useConfigurationEffect =
27+
ReactNativeFeatureFlags.configurePressabilityDuringInsertion()
28+
? useInsertionEffect
29+
: useEffect;
30+
2031
/**
2132
* Creates a persistent instance of `Pressability` that automatically configures
2233
* itself and resets. Accepts null `config` to support lazy initialization. Once
@@ -40,15 +51,15 @@ export default function usePressability(
4051

4152
// On the initial mount, this is a no-op. On updates, `pressability` will be
4253
// re-configured to use the new configuration.
43-
useEffect(() => {
54+
useConfigurationEffect(() => {
4455
if (config != null && pressability != null) {
4556
pressability.configure(config);
4657
}
4758
}, [config, pressability]);
4859

4960
// On unmount, reset pending state and timers inside `pressability`. This is
5061
// a separate effect because we do not want to reset when `config` changes.
51-
useEffect(() => {
62+
useConfigurationEffect(() => {
5263
if (pressability != null) {
5364
return () => {
5465
pressability.reset();

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -924,6 +924,17 @@ const definitions: FeatureFlagDefinitions = {
924924
},
925925
ossReleaseStage: 'none',
926926
},
927+
configurePressabilityDuringInsertion: {
928+
defaultValue: false,
929+
metadata: {
930+
dateAdded: '2025-10-27',
931+
description:
932+
'Configure Pressability during insertion and no longer unmount when hidden.',
933+
expectedReleaseValue: true,
934+
purpose: 'experimentation',
935+
},
936+
ossReleaseStage: 'none',
937+
},
927938
deferFlatListFocusChangeRenderUpdate: {
928939
defaultValue: false,
929940
metadata: {

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<<9bb9145e823dae3447fa8fbb31676b37>>
7+
* @generated SignedSource<<d8ae80ae606b6cf56ea06866b5e5ac99>>
88
* @flow strict
99
* @noformat
1010
*/
@@ -31,6 +31,7 @@ export type ReactNativeFeatureFlagsJsOnly = $ReadOnly<{
3131
jsOnlyTestFlag: Getter<boolean>,
3232
animatedShouldDebounceQueueFlush: Getter<boolean>,
3333
animatedShouldUseSingleOp: Getter<boolean>,
34+
configurePressabilityDuringInsertion: Getter<boolean>,
3435
deferFlatListFocusChangeRenderUpdate: Getter<boolean>,
3536
disableMaintainVisibleContentPosition: Getter<boolean>,
3637
enableAccessToHostTreeInFabric: Getter<boolean>,
@@ -147,6 +148,11 @@ export const animatedShouldDebounceQueueFlush: Getter<boolean> = createJavaScrip
147148
*/
148149
export const animatedShouldUseSingleOp: Getter<boolean> = createJavaScriptFlagGetter('animatedShouldUseSingleOp', false);
149150

151+
/**
152+
* Configure Pressability during insertion and no longer unmount when hidden.
153+
*/
154+
export const configurePressabilityDuringInsertion: Getter<boolean> = createJavaScriptFlagGetter('configurePressabilityDuringInsertion', false);
155+
150156
/**
151157
* Use the deferred cell render update mechanism for focus change in FlatList.
152158
*/

0 commit comments

Comments
 (0)