From d0d853b2524f2a4da6aa9613bc8fde1bc4dbc1cc Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Tue, 26 Aug 2025 15:12:41 -0700 Subject: [PATCH] add option to disable prop scrollView.maintainVisibleContentPosition (#53465) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/53465 changelog: [internal] I am debugging an issue with Fabric View Culling + immediate state update. The problem appears to be in logic handling `maintainVisibleContentPosition`. I want to try to disable the prop to see if the problem goes away. Reviewed By: rshest Differential Revision: D81030436 fbshipit-source-id: 8efeb1151ad3e12b812cafd073348502510ef01d --- .../Libraries/Components/ScrollView/ScrollView.js | 12 ++++++++++-- .../featureflags/ReactNativeFeatureFlags.config.js | 11 +++++++++++ .../private/featureflags/ReactNativeFeatureFlags.js | 8 +++++++- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/packages/react-native/Libraries/Components/ScrollView/ScrollView.js b/packages/react-native/Libraries/Components/ScrollView/ScrollView.js index 64c7ee2f923..179cd3320b1 100644 --- a/packages/react-native/Libraries/Components/ScrollView/ScrollView.js +++ b/packages/react-native/Libraries/Components/ScrollView/ScrollView.js @@ -31,6 +31,7 @@ import { VScrollContentViewNativeComponent, VScrollViewNativeComponent, } from '../../../src/private/components/scrollview/VScrollViewNativeComponents'; +import * as ReactNativeFeatureFlags from '../../../src/private/featureflags/ReactNativeFeatureFlags'; import AnimatedImplementation from '../../Animated/AnimatedImplementation'; import FrameRateLogger from '../../Interaction/FrameRateLogger'; import {findNodeHandle} from '../../ReactNative/RendererProxy'; @@ -1752,8 +1753,11 @@ class ScrollView extends React.Component { const baseStyle = horizontal ? styles.baseHorizontal : styles.baseVertical; - const {experimental_endDraggingSensitivityMultiplier, ...otherProps} = - this.props; + const { + experimental_endDraggingSensitivityMultiplier, + maintainVisibleContentPosition, + ...otherProps + } = this.props; const props = { ...otherProps, alwaysBounceHorizontal, @@ -1806,6 +1810,10 @@ class ScrollView extends React.Component { this.props.snapToInterval != null || this.props.snapToOffsets != null, }), + maintainVisibleContentPosition: + ReactNativeFeatureFlags.disableMaintainVisibleContentPosition() + ? undefined + : this.props.maintainVisibleContentPosition, }; const {decelerationRate} = this.props; diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index afe6110129f..a562ba4b6bf 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -818,6 +818,17 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, + disableMaintainVisibleContentPosition: { + defaultValue: false, + metadata: { + dateAdded: '2025-08-26', + description: + 'Disable prop maintainVisibleContentPosition in ScrollView', + expectedReleaseValue: false, + purpose: 'experimentation', + }, + ossReleaseStage: 'none', + }, enableAccessToHostTreeInFabric: { defaultValue: true, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 0e2941d0e64..065614781ea 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<> + * @generated SignedSource<<276b1579eef10e63c77752017b97985f>> * @flow strict * @noformat */ @@ -32,6 +32,7 @@ export type ReactNativeFeatureFlagsJsOnly = $ReadOnly<{ animatedShouldDebounceQueueFlush: Getter, animatedShouldUseSingleOp: Getter, deferFlatListFocusChangeRenderUpdate: Getter, + disableMaintainVisibleContentPosition: Getter, enableAccessToHostTreeInFabric: Getter, fixVirtualizeListCollapseWindowSize: Getter, isLayoutAnimationEnabled: Getter, @@ -138,6 +139,11 @@ export const animatedShouldUseSingleOp: Getter = createJavaScriptFlagGe */ export const deferFlatListFocusChangeRenderUpdate: Getter = createJavaScriptFlagGetter('deferFlatListFocusChangeRenderUpdate', false); +/** + * Disable prop maintainVisibleContentPosition in ScrollView + */ +export const disableMaintainVisibleContentPosition: Getter = createJavaScriptFlagGetter('disableMaintainVisibleContentPosition', false); + /** * Enables access to the host tree in Fabric using DOM-compatible APIs. */