render()

in src/native-common/ScrollView.tsx [45:141]


    render() {
        let scrollThrottle = this.props.scrollEventThrottle || 16;

        if (scrollThrottle === 0) {
            // Fire at 60fps
            scrollThrottle = 16;
        }

        const layoutCallback = this.props.onLayout ?
            // We have a callback function, call the wrapper
            this._onLayout :
            undefined;

        let scrollHandler;
        if (this.props.scrollXAnimatedValue || this.props.scrollYAnimatedValue) {
            // For more details on this craziness, reference:
            // https://facebook.github.io/react-native/docs/animated#handling-gestures-and-other-events
            const handlerWrapper: RN.EventMapping = {
                nativeEvent: {
                    contentOffset: { },
                },
            };
            if (this.props.scrollXAnimatedValue) {
                handlerWrapper.nativeEvent.contentOffset.x = this.props.scrollXAnimatedValue;
            }
            if (this.props.scrollYAnimatedValue) {
                handlerWrapper.nativeEvent.contentOffset.y = this.props.scrollYAnimatedValue;
            }
            const eventConfig: RN.AnimatedEventConfig<RN.NativeScrollEvent> = {
                useNativeDriver: true,
            };
            if (this.props.onScroll) {
                eventConfig.listener = this._onScroll;
            }
            // react-native.d.ts is wrong for the eventconfig typing, so casting to any for now.
            scrollHandler = RN.Animated.event([handlerWrapper], eventConfig as any);
        } else if (this.props.onScroll) {
            scrollHandler = this._onScroll;
        } else {
            scrollHandler = undefined;
        }

        // 1) keyboardShouldPersistTaps may be overridden, superceding all other settings
        // 2) in the absence of any other setting, 'never' is the default
        // 3) if a boolean is seen, translate to 'always' or 'never' as the boolean is deprecated
        // 4) it is also possible to see a string value of 'handled'
        let keyboardShouldPersistTaps: ScrollViewProps['keyboardShouldPersistTaps'] = 'never';
        if (overrideKeyboardShouldPersistTaps || this.props.keyboardShouldPersistTaps === true) {
            // If there is an override or a boolean true, translate it to 'always'
            keyboardShouldPersistTaps = 'always';
        } else if (typeof this.props.keyboardShouldPersistTaps === 'string') {
            // If there is no override, and a string && non-boolean was provided, use it without translation
            keyboardShouldPersistTaps = this.props.keyboardShouldPersistTaps;
        }

        // NOTE: We are setting `automaticallyAdjustContentInsets` to false
        // (http://facebook.github.io/react-native/docs/scrollview.html#automaticallyadjustcontentinsets). The
        // 'automaticallyAdjustContentInsets' property is designed to offset the ScrollView's content to account for the
        // navigation and tab bars in iOS.
        // (navigationBarHidden={true}). We believe that React Native may not be calculating the content insets for the
        // ScrollView correctly in this situation. Disabling this calculation seems to fix the ScrollView inset issues.
        // Currently RX does not expose any components that would require `automaticallyAdjustContentInsets` to be
        // set to true.
        // We also set removeClippedSubviews to false, overriding the default value. Most of the scroll views
        // we use are virtualized anyway.

        const internalProps: RN.ScrollViewProps & React.Props<RN.ScrollView> = {
            ref: this._setNativeComponent,
            // Bug in react-native.d.ts.  style should be "style?: StyleProp<ScrollViewStyle>;" but instead is ViewStyle.
            style: this.props.style as any,
            onScroll: scrollHandler,
            automaticallyAdjustContentInsets: false,
            showsHorizontalScrollIndicator: this.props.showsHorizontalScrollIndicator,
            showsVerticalScrollIndicator: this.props.showsVerticalScrollIndicator,
            keyboardDismissMode:  this.props.keyboardDismissMode,
            keyboardShouldPersistTaps: keyboardShouldPersistTaps,
            scrollEnabled: this.props.scrollEnabled,
            onContentSizeChange: this.props.onContentSizeChange,
            onLayout: layoutCallback,
            scrollEventThrottle: scrollThrottle,
            horizontal: this.props.horizontal,
            bounces: this.props.bounces,
            pagingEnabled: this.props.pagingEnabled,
            snapToInterval: this.props.snapToInterval,
            decelerationRate: typeof this.props.snapToInterval === 'number' ? 'fast' : undefined,
            scrollsToTop: this.props.scrollsToTop,
            removeClippedSubviews: false,
            overScrollMode: this.props.overScrollMode,
            scrollIndicatorInsets: this.props.scrollIndicatorInsets,
            onScrollBeginDrag: this.props.onScrollBeginDrag,
            onScrollEndDrag: this.props.onScrollEndDrag,
            children: this.props.children,
            testID: this.props.testId,
        };

        return this._render(internalProps);
    }