From 1e6404ed7a19f480ebd025ded54823fd6daf846f Mon Sep 17 00:00:00 2001 From: eeremeev Date: Fri, 14 Dec 2018 16:10:05 +0500 Subject: [PATCH] Fix case when scrollToPosition will not update internal state in React >= 16.4. In cases when the Grid component is controlled (WindowScroller, MultiGrid) fields scrollLeft and scrollTop ware not updated on setState call. getDerivedStateFromProps is called before every render starting from React 16.4 and those fields were overridden by previous props. --- source/Grid/Grid.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/source/Grid/Grid.js b/source/Grid/Grid.js index e2f439214..9f6622015 100644 --- a/source/Grid/Grid.js +++ b/source/Grid/Grid.js @@ -232,6 +232,8 @@ type InstanceProps = { prevIsScrolling: boolean, prevScrollToColumn: number, prevScrollToRow: number, + prevScrollLeft: ?number, + prevScrollTop: ?number, columnSizeAndPositionManager: ScalingCellSizeAndPositionManager, rowSizeAndPositionManager: ScalingCellSizeAndPositionManager, @@ -343,6 +345,8 @@ class Grid extends React.PureComponent { prevIsScrolling: props.isScrolling === true, prevScrollToColumn: props.scrollToColumn, prevScrollToRow: props.scrollToRow, + prevScrollLeft: props.scrollLeft, + prevScrollTop: props.scrollTop, scrollbarSize: 0, scrollbarSizeMeasured: false, @@ -350,8 +354,8 @@ class Grid extends React.PureComponent { isScrolling: false, scrollDirectionHorizontal: SCROLL_DIRECTION_FORWARD, scrollDirectionVertical: SCROLL_DIRECTION_FORWARD, - scrollLeft: 0, - scrollTop: 0, + scrollLeft: props.scrollLeft || 0, + scrollTop: props.scrollTop || 0, scrollPositionChangeReason: null, needToResetStyleCache: false, @@ -821,6 +825,7 @@ class Grid extends React.PureComponent { prevState: State, ): $Shape { const newState = {}; + let {instanceProps} = prevState; if ( (nextProps.columnCount === 0 && prevState.scrollLeft !== 0) || @@ -832,9 +837,10 @@ class Grid extends React.PureComponent { // only use scroll{Left,Top} from props if scrollTo{Column,Row} isn't specified // scrollTo{Column,Row} should override scroll{Left,Top} } else if ( - (nextProps.scrollLeft !== prevState.scrollLeft && + (nextProps.scrollLeft !== instanceProps.prevScrollLeft && nextProps.scrollToColumn < 0) || - (nextProps.scrollTop !== prevState.scrollTop && nextProps.scrollToRow < 0) + (nextProps.scrollTop !== instanceProps.prevScrollTop && + nextProps.scrollToRow < 0) ) { Object.assign( newState, @@ -846,8 +852,6 @@ class Grid extends React.PureComponent { ); } - let {instanceProps} = prevState; - // Initially we should not clearStyleCache newState.needToResetStyleCache = false; if ( @@ -944,6 +948,8 @@ class Grid extends React.PureComponent { instanceProps.prevRowHeight = nextProps.rowHeight; instanceProps.prevScrollToColumn = nextProps.scrollToColumn; instanceProps.prevScrollToRow = nextProps.scrollToRow; + instanceProps.prevScrollLeft = nextProps.scrollLeft; + instanceProps.prevScrollTop = nextProps.scrollTop; // getting scrollBarSize (moved from componentWillMount) instanceProps.scrollbarSize = nextProps.getScrollbarSize();