[fix] ScrollView 'setNativeProps'

Fix #709
Close #710
This commit is contained in:
Nicolas Gallagher
2017-11-15 14:39:58 -08:00
parent 92952ee746
commit a748b7e606
3 changed files with 79 additions and 55 deletions

View File

@@ -49,6 +49,8 @@ const normalizeScrollEvent = e => ({
* Encapsulates the Web-specific scroll throttling and disabling logic
*/
export default class ScrollViewBase extends Component {
_viewRef: View;
static propTypes = {
...ViewPropTypes,
onMomentumScrollBegin: func,
@@ -73,6 +75,66 @@ export default class ScrollViewBase extends Component {
_debouncedOnScrollEnd = debounce(this._handleScrollEnd, 100);
_state = { isScrolling: false, scrollLastTick: 0 };
setNativeProps(props: Object) {
if (this._viewRef) {
this._viewRef.setNativeProps(props);
}
}
render() {
const {
scrollEnabled,
style,
/* eslint-disable */
alwaysBounceHorizontal,
alwaysBounceVertical,
automaticallyAdjustContentInsets,
bounces,
bouncesZoom,
canCancelContentTouches,
centerContent,
contentInset,
contentInsetAdjustmentBehavior,
contentOffset,
decelerationRate,
directionalLockEnabled,
endFillColor,
indicatorStyle,
keyboardShouldPersistTaps,
maximumZoomScale,
minimumZoomScale,
onMomentumScrollBegin,
onMomentumScrollEnd,
onScrollBeginDrag,
onScrollEndDrag,
overScrollMode,
pinchGestureEnabled,
removeClippedSubviews,
scrollEventThrottle,
scrollIndicatorInsets,
scrollPerfTag,
scrollsToTop,
showsHorizontalScrollIndicator,
showsVerticalScrollIndicator,
snapToInterval,
snapToAlignment,
zoomScale,
/* eslint-enable */
...other
} = this.props;
return (
<View
{...other}
onScroll={this._handleScroll}
onTouchMove={this._createPreventableScrollHandler(this.props.onTouchMove)}
onWheel={this._createPreventableScrollHandler(this.props.onWheel)}
ref={this._setViewRef}
style={[style, !scrollEnabled && styles.scrollDisabled]}
/>
);
}
_createPreventableScrollHandler = (handler: Function) => {
return (e: Object) => {
if (this.props.scrollEnabled) {
@@ -124,63 +186,14 @@ export default class ScrollViewBase extends Component {
}
}
_setViewRef = (element: View) => {
this._viewRef = element;
};
_shouldEmitScrollEvent(lastTick: number, eventThrottle: number) {
const timeSinceLastTick = Date.now() - lastTick;
return eventThrottle > 0 && timeSinceLastTick >= eventThrottle;
}
render() {
const {
scrollEnabled,
style,
/* eslint-disable */
alwaysBounceHorizontal,
alwaysBounceVertical,
automaticallyAdjustContentInsets,
bounces,
bouncesZoom,
canCancelContentTouches,
centerContent,
contentInset,
contentInsetAdjustmentBehavior,
contentOffset,
decelerationRate,
directionalLockEnabled,
endFillColor,
indicatorStyle,
keyboardShouldPersistTaps,
maximumZoomScale,
minimumZoomScale,
onMomentumScrollBegin,
onMomentumScrollEnd,
onScrollBeginDrag,
onScrollEndDrag,
overScrollMode,
pinchGestureEnabled,
removeClippedSubviews,
scrollEventThrottle,
scrollIndicatorInsets,
scrollPerfTag,
scrollsToTop,
showsHorizontalScrollIndicator,
showsVerticalScrollIndicator,
snapToInterval,
snapToAlignment,
zoomScale,
/* eslint-enable */
...other
} = this.props;
return (
<View
{...other}
onScroll={this._handleScroll}
onTouchMove={this._createPreventableScrollHandler(this.props.onTouchMove)}
onWheel={this._createPreventableScrollHandler(this.props.onWheel)}
style={[style, !scrollEnabled && styles.scrollDisabled]}
/>
);
}
}
// Chrome doesn't support e.preventDefault in this case; touch-action must be

View File

@@ -1,5 +1,14 @@
/* eslint-env jasmine, jest */
import React from 'react';
import ScrollView from '..';
import { mount } from 'enzyme';
describe('components/ScrollView', () => {
test('NO TEST COVERAGE');
test('instance method setNativeProps', () => {
const instance = mount(<ScrollView />).instance();
expect(() => {
instance.setNativeProps();
}).not.toThrow();
});
});

View File

@@ -49,7 +49,9 @@ const ScrollView = createReactClass({
},
setNativeProps(props: Object) {
this._scrollViewRef.setNativeProps(props);
if (this._scrollViewRef) {
this._scrollViewRef.setNativeProps(props);
}
},
/**