From 0e8f684a5cba204ca3c72e707a2a1ea506f8e52b Mon Sep 17 00:00:00 2001 From: Tim Yung Date: Tue, 25 Jun 2024 11:17:45 -0700 Subject: [PATCH] RN: Refactor ScrollView Native Component Imports Summary: Refactors the native component imports in `ScrollView` so that 1) they create less clutter in the `ScrollView` implementation file, and 2) they offer more efficient import inlining. Currently, `ScrollView` has to evaluate both horizontal and vertical components even though only one may be used. Now this optimization is possible. Changelog: [Internal] Differential Revision: D59015990 --- .../Components/ScrollView/ScrollView.js | 75 ++++++++----------- .../components/HScrollViewNativeComponents.js | 30 ++++++++ .../components/VScrollViewNativeComponents.js | 25 +++++++ 3 files changed, 85 insertions(+), 45 deletions(-) create mode 100644 packages/react-native/src/private/core/components/HScrollViewNativeComponents.js create mode 100644 packages/react-native/src/private/core/components/VScrollViewNativeComponents.js diff --git a/packages/react-native/Libraries/Components/ScrollView/ScrollView.js b/packages/react-native/Libraries/Components/ScrollView/ScrollView.js index dbe5bf1f218a..7ed852f43543 100644 --- a/packages/react-native/Libraries/Components/ScrollView/ScrollView.js +++ b/packages/react-native/Libraries/Components/ScrollView/ScrollView.js @@ -20,9 +20,18 @@ import type { } from '../../Types/CoreEventTypes'; import type {EventSubscription} from '../../vendor/emitter/EventEmitter'; import type {KeyboardEvent, KeyboardMetrics} from '../Keyboard/Keyboard'; +import typeof View from '../View/View'; import type {ViewProps} from '../View/ViewPropTypes'; import type {Props as ScrollViewStickyHeaderProps} from './ScrollViewStickyHeader'; +import { + HScrollContentViewNativeComponent, + HScrollViewNativeComponent, +} from '../../../src/private/core/components/HScrollViewNativeComponents'; +import { + VScrollContentViewNativeComponent, + VScrollViewNativeComponent, +} from '../../../src/private/core/components/VScrollViewNativeComponents'; import AnimatedImplementation from '../../Animated/AnimatedImplementation'; import FrameRateLogger from '../../Interaction/FrameRateLogger'; import {findNodeHandle} from '../../ReactNative/RendererProxy'; @@ -36,14 +45,9 @@ import Platform from '../../Utilities/Platform'; import EventEmitter from '../../vendor/emitter/EventEmitter'; import Keyboard from '../Keyboard/Keyboard'; import TextInputState from '../TextInput/TextInputState'; -import View from '../View/View'; -import AndroidHorizontalScrollContentViewNativeComponent from './AndroidHorizontalScrollContentViewNativeComponent'; -import AndroidHorizontalScrollViewNativeComponent from './AndroidHorizontalScrollViewNativeComponent'; import processDecelerationRate from './processDecelerationRate'; -import ScrollContentViewNativeComponent from './ScrollContentViewNativeComponent'; import Commands from './ScrollViewCommands'; import ScrollViewContext, {HORIZONTAL, VERTICAL} from './ScrollViewContext'; -import ScrollViewNativeComponent from './ScrollViewNativeComponent'; import ScrollViewStickyHeader from './ScrollViewStickyHeader'; import invariant from 'invariant'; import memoize from 'memoize-one'; @@ -54,26 +58,6 @@ if (Platform.OS === 'ios') { require('../../Renderer/shims/ReactNative'); // Force side effects to prevent T55744311 } -const {NativeHorizontalScrollViewTuple, NativeVerticalScrollViewTuple} = - Platform.OS === 'android' - ? { - NativeHorizontalScrollViewTuple: [ - AndroidHorizontalScrollViewNativeComponent, - AndroidHorizontalScrollContentViewNativeComponent, - ], - NativeVerticalScrollViewTuple: [ScrollViewNativeComponent, View], - } - : { - NativeHorizontalScrollViewTuple: [ - ScrollViewNativeComponent, - ScrollContentViewNativeComponent, - ], - NativeVerticalScrollViewTuple: [ - ScrollViewNativeComponent, - ScrollContentViewNativeComponent, - ], - }; - /* * iOS scroll event timing nuances: * =============================== @@ -173,7 +157,7 @@ type PublicScrollViewInstance = $ReadOnly<{| ...ScrollViewImperativeMethods, |}>; -type InnerViewInstance = React.ElementRef; +type InnerViewInstance = React.ElementRef; type IOSProps = $ReadOnly<{| /** @@ -1691,13 +1675,18 @@ class ScrollView extends React.Component { }; render(): React.Node | React.Element { - const [NativeDirectionalScrollView, NativeDirectionalScrollContentView] = - this.props.horizontal === true - ? NativeHorizontalScrollViewTuple - : NativeVerticalScrollViewTuple; + const horizontal = this.props.horizontal === true; + + const NativeScrollView = horizontal + ? HScrollViewNativeComponent + : VScrollViewNativeComponent; + + const NativeScrollContentView = horizontal + ? HScrollContentViewNativeComponent + : VScrollContentViewNativeComponent; const contentContainerStyle = [ - this.props.horizontal === true && styles.contentContainerHorizontal, + horizontal && styles.contentContainerHorizontal, this.props.contentContainerStyle, ]; if (__DEV__ && this.props.style !== undefined) { @@ -1759,8 +1748,7 @@ class ScrollView extends React.Component { }); } children = ( - + {children} ); @@ -1776,7 +1764,7 @@ class ScrollView extends React.Component { (Platform.OS === 'android' && this.props.snapToAlignment != null); const contentContainer = ( - { collapsable={false} collapsableChildren={!preserveChildren}> {children} - + ); const alwaysBounceHorizontal = @@ -1803,10 +1791,7 @@ class ScrollView extends React.Component { ? this.props.alwaysBounceVertical : !this.props.horizontal; - const baseStyle = - this.props.horizontal === true - ? styles.baseHorizontal - : styles.baseVertical; + const baseStyle = horizontal ? styles.baseHorizontal : styles.baseVertical; const {experimental_endDraggingSensitivityMultiplier, ...otherProps} = this.props; @@ -1879,10 +1864,10 @@ class ScrollView extends React.Component { if (Platform.OS === 'ios') { // On iOS the RefreshControl is a child of the ScrollView. return ( - + {refreshControl} {contentContainer} - + ); } else if (Platform.OS === 'android') { // On Android wrap the ScrollView with a AndroidSwipeRefreshLayout. @@ -1896,19 +1881,19 @@ class ScrollView extends React.Component { return React.cloneElement( refreshControl, {style: StyleSheet.compose(baseStyle, outer)}, - {contentContainer} - , + , ); } } return ( - + {contentContainer} - + ); } } diff --git a/packages/react-native/src/private/core/components/HScrollViewNativeComponents.js b/packages/react-native/src/private/core/components/HScrollViewNativeComponents.js new file mode 100644 index 000000000000..baaff2500011 --- /dev/null +++ b/packages/react-native/src/private/core/components/HScrollViewNativeComponents.js @@ -0,0 +1,30 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + * @oncall react_native + */ + +import type {ScrollViewNativeProps} from '../../../../Libraries/Components/ScrollView/ScrollViewNativeComponentType'; +import type {ViewProps} from '../../../../Libraries/Components/View/ViewPropTypes'; +import type {HostComponent} from '../../../../Libraries/Renderer/shims/ReactNativeTypes'; + +import AndroidHorizontalScrollViewNativeComponent from '../../../../Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent'; +import ScrollContentViewNativeComponent from '../../../../Libraries/Components/ScrollView/ScrollContentViewNativeComponent'; +import ScrollViewNativeComponent from '../../../../Libraries/Components/ScrollView/ScrollViewNativeComponent'; +import Platform from '../../../../Libraries/Utilities/Platform'; +import AndroidHorizontalScrollContentViewNativeComponent from '../../specs/components/AndroidHorizontalScrollContentViewNativeComponent'; + +export const HScrollViewNativeComponent: HostComponent = + Platform.OS === 'android' + ? AndroidHorizontalScrollViewNativeComponent + : ScrollViewNativeComponent; + +export const HScrollContentViewNativeComponent: HostComponent = + Platform.OS === 'android' + ? AndroidHorizontalScrollContentViewNativeComponent + : ScrollContentViewNativeComponent; diff --git a/packages/react-native/src/private/core/components/VScrollViewNativeComponents.js b/packages/react-native/src/private/core/components/VScrollViewNativeComponents.js new file mode 100644 index 000000000000..00aeda0d5dda --- /dev/null +++ b/packages/react-native/src/private/core/components/VScrollViewNativeComponents.js @@ -0,0 +1,25 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + * @oncall react_native + */ + +import type {ScrollViewNativeProps} from '../../../../Libraries/Components/ScrollView/ScrollViewNativeComponentType'; +import type {ViewProps} from '../../../../Libraries/Components/View/ViewPropTypes'; +import type {HostComponent} from '../../../../Libraries/Renderer/shims/ReactNativeTypes'; + +import ScrollContentViewNativeComponent from '../../../../Libraries/Components/ScrollView/ScrollContentViewNativeComponent'; +import ScrollViewNativeComponent from '../../../../Libraries/Components/ScrollView/ScrollViewNativeComponent'; +import View from '../../../../Libraries/Components/View/View'; +import Platform from '../../../../Libraries/Utilities/Platform'; + +export const VScrollViewNativeComponent: HostComponent = + ScrollViewNativeComponent; + +export const VScrollContentViewNativeComponent: HostComponent = + Platform.OS === 'android' ? View : ScrollContentViewNativeComponent;