From 3d5204cd34e7a0d292d80b13cec69fcfc6ed9dc7 Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Fri, 4 Aug 2023 11:23:45 -0700 Subject: [PATCH] Add MC to disable `onScroll` requiring `scrollEventThrottle` on iOS. (#38742) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/38742 If you try to add an `onScroll` event listener on iOS, you will get a warning that you must additionally add a `scrollEventThrottle`, otherwise you will only receive a single event throughout the duration of the gesturing. Values under 17ms are unthrottled, so it is common to see components passing magic values `16` and `0.0001` to ask for full events. This behavior is inconsistent with Android, Web, and Windows. This change runs an experiment on iOS to continuously fire scroll events to users of `onScroll` without `scrollEventThrottle`. Because there are warnings already, I think this case will be rare, and any code written for Android will already have to be written to be compatible with it. I intentionally left the warning in for now, so that folks don't add new code relying on this QE while it is being tested. Changelog: [Internal] Reviewed By: yungsters Differential Revision: D47975260 fbshipit-source-id: 8f182c5514cc557e1804586e8cbc68fc54502d83 --- .../ComponentViews/ScrollView/RCTScrollViewComponentView.mm | 3 ++- packages/react-native/React/Fabric/RCTSurfacePresenter.mm | 4 ++++ .../react-native/ReactCommon/react/utils/CoreFeatures.cpp | 1 + packages/react-native/ReactCommon/react/utils/CoreFeatures.h | 4 ++++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm index 94c82ad08ad..5c3f18d1c16 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm @@ -442,7 +442,8 @@ static void RCTSendScrollEventForNativeAnimations_DEPRECATED(UIScrollView *scrol } NSTimeInterval now = CACurrentMediaTime(); - if ((_lastScrollEventDispatchTime == 0) || (now - _lastScrollEventDispatchTime > _scrollEventThrottle)) { + if (CoreFeatures::disableScrollEventThrottleRequirement || (_lastScrollEventDispatchTime == 0) || + (now - _lastScrollEventDispatchTime > _scrollEventThrottle)) { _lastScrollEventDispatchTime = now; if (_eventEmitter) { static_cast(*_eventEmitter).onScroll([self _scrollViewMetrics]); diff --git a/packages/react-native/React/Fabric/RCTSurfacePresenter.mm b/packages/react-native/React/Fabric/RCTSurfacePresenter.mm index d17a646fb19..6c2e6936774 100644 --- a/packages/react-native/React/Fabric/RCTSurfacePresenter.mm +++ b/packages/react-native/React/Fabric/RCTSurfacePresenter.mm @@ -280,6 +280,10 @@ static BackgroundExecutor RCTGetBackgroundExecutor() CoreFeatures::enableMountHooks = true; } + if (reactNativeConfig && reactNativeConfig->getBool("react_fabric:disable_scroll_event_throttle_requirement")) { + CoreFeatures::disableScrollEventThrottleRequirement = true; + } + auto componentRegistryFactory = [factory = wrapManagedObject(_mountingManager.componentViewRegistry.componentViewFactory)]( EventDispatcher::Weak const &eventDispatcher, ContextContainer::Shared const &contextContainer) { diff --git a/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp b/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp index e44b0190501..0554485f543 100644 --- a/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp +++ b/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp @@ -19,5 +19,6 @@ bool CoreFeatures::enableGranularScrollViewStateUpdatesIOS = false; bool CoreFeatures::enableMountHooks = false; bool CoreFeatures::doNotSwapLeftAndRightOnAndroidInLTR = false; bool CoreFeatures::enableCleanParagraphYogaNode = false; +bool CoreFeatures::disableScrollEventThrottleRequirement = false; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/utils/CoreFeatures.h b/packages/react-native/ReactCommon/react/utils/CoreFeatures.h index 2d693ffc68b..3c9af96e609 100644 --- a/packages/react-native/ReactCommon/react/utils/CoreFeatures.h +++ b/packages/react-native/ReactCommon/react/utils/CoreFeatures.h @@ -56,6 +56,10 @@ class CoreFeatures { // Clean yoga node when does not change. static bool enableCleanParagraphYogaNode; + + // Fire `onScroll` events continuously on iOS without a `scrollEventThrottle` + // props, and provide continuous `onScroll` upates like other platforms. + static bool disableScrollEventThrottleRequirement; }; } // namespace facebook::react