Update VirtualizedList to not throw with double constructor

Summary: constructor shouldn't have side effects.

Reviewed By: sahrens

Differential Revision: D7146018

fbshipit-source-id: 0ca311e48d6bad81988ed48605c8134068c482da
This commit is contained in:
Sophie Alpert 2018-03-05 14:12:23 -08:00 committed by Facebook Github Bot
parent 4466b6fa7c
commit 19b9851999

View File

@ -442,6 +442,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
getScrollMetrics: PropTypes.func, getScrollMetrics: PropTypes.func,
horizontal: PropTypes.bool, horizontal: PropTypes.bool,
getOutermostParentListRef: PropTypes.func, getOutermostParentListRef: PropTypes.func,
getNestedChildState: PropTypes.func,
registerAsNestedChild: PropTypes.func, registerAsNestedChild: PropTypes.func,
unregisterAsNestedChild: PropTypes.func, unregisterAsNestedChild: PropTypes.func,
}), }),
@ -452,6 +453,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
getScrollMetrics: PropTypes.func, getScrollMetrics: PropTypes.func,
horizontal: PropTypes.bool, horizontal: PropTypes.bool,
getOutermostParentListRef: PropTypes.func, getOutermostParentListRef: PropTypes.func,
getNestedChildState: PropTypes.func,
registerAsNestedChild: PropTypes.func, registerAsNestedChild: PropTypes.func,
unregisterAsNestedChild: PropTypes.func, unregisterAsNestedChild: PropTypes.func,
}), }),
@ -463,6 +465,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
getScrollMetrics: this._getScrollMetrics, getScrollMetrics: this._getScrollMetrics,
horizontal: this.props.horizontal, horizontal: this.props.horizontal,
getOutermostParentListRef: this._getOutermostParentListRef, getOutermostParentListRef: this._getOutermostParentListRef,
getNestedChildState: this._getNestedChildState,
registerAsNestedChild: this._registerAsNestedChild, registerAsNestedChild: this._registerAsNestedChild,
unregisterAsNestedChild: this._unregisterAsNestedChild, unregisterAsNestedChild: this._unregisterAsNestedChild,
}, },
@ -492,6 +495,11 @@ class VirtualizedList extends React.PureComponent<Props, State> {
} }
}; };
_getNestedChildState = (key: string): ?ChildListState => {
const existingChildData = this._nestedChildLists.get(key);
return existingChildData && existingChildData.state;
};
_registerAsNestedChild = (childList: { _registerAsNestedChild = (childList: {
cellKey: string, cellKey: string,
key: string, key: string,
@ -518,8 +526,6 @@ class VirtualizedList extends React.PureComponent<Props, State> {
if (this._hasInteracted) { if (this._hasInteracted) {
childList.ref.recordInteraction(); childList.ref.recordInteraction();
} }
return existingChildData && existingChildData.state;
}; };
_unregisterAsNestedChild = (childList: { _unregisterAsNestedChild = (childList: {
@ -577,11 +583,9 @@ class VirtualizedList extends React.PureComponent<Props, State> {
}; };
if (this._isNestedWithSameOrientation()) { if (this._isNestedWithSameOrientation()) {
const storedState = this.context.virtualizedList.registerAsNestedChild({ const storedState = this.context.virtualizedList.getNestedChildState(
cellKey: this._getCellKey(), this.props.listKey || this._getCellKey(),
key: this.props.listKey || this._getCellKey(), );
ref: this,
});
if (storedState) { if (storedState) {
initialState = storedState; initialState = storedState;
this.state = storedState; this.state = storedState;
@ -592,6 +596,16 @@ class VirtualizedList extends React.PureComponent<Props, State> {
this.state = initialState; this.state = initialState;
} }
componentDidMount() {
if (this._isNestedWithSameOrientation()) {
this.context.virtualizedList.registerAsNestedChild({
cellKey: this._getCellKey(),
key: this.props.listKey || this._getCellKey(),
ref: this,
});
}
}
componentWillUnmount() { componentWillUnmount() {
if (this._isNestedWithSameOrientation()) { if (this._isNestedWithSameOrientation()) {
this.context.virtualizedList.unregisterAsNestedChild({ this.context.virtualizedList.unregisterAsNestedChild({
@ -611,29 +625,17 @@ class VirtualizedList extends React.PureComponent<Props, State> {
this._fillRateHelper.deactivateAndFlush(); this._fillRateHelper.deactivateAndFlush();
} }
UNSAFE_componentWillReceiveProps(newProps: Props) { static getDerivedStateFromProps(newProps: Props, prevState: State) {
const {data, extraData, getItemCount, maxToRenderPerBatch} = newProps; const {data, extraData, getItemCount, maxToRenderPerBatch} = newProps;
// first and last could be stale (e.g. if a new, shorter items props is passed in), so we make // first and last could be stale (e.g. if a new, shorter items props is passed in), so we make
// sure we're rendering a reasonable range here. // sure we're rendering a reasonable range here.
this.setState({ return {
first: Math.max( first: Math.max(
0, 0,
Math.min( Math.min(prevState.first, getItemCount(data) - 1 - maxToRenderPerBatch),
this.state.first,
getItemCount(data) - 1 - maxToRenderPerBatch,
),
), ),
last: Math.max(0, Math.min(this.state.last, getItemCount(data) - 1)), last: Math.max(0, Math.min(prevState.last, getItemCount(data) - 1)),
}); };
if (data !== this.props.data || extraData !== this.props.extraData) {
this._hasDataChangedSinceEndReached = true;
// clear the viewableIndices cache to also trigger
// the onViewableItemsChanged callback with the new data
this._viewabilityTuples.forEach(tuple => {
tuple.viewabilityHelper.resetViewableIndices();
});
}
} }
_pushCells( _pushCells(
@ -916,7 +918,17 @@ class VirtualizedList extends React.PureComponent<Props, State> {
} }
} }
componentDidUpdate() { componentDidUpdate(prevProps: Props) {
const {data, extraData} = this.props;
if (data !== prevProps.data || extraData !== prevProps.extraData) {
this._hasDataChangedSinceEndReached = true;
// clear the viewableIndices cache to also trigger
// the onViewableItemsChanged callback with the new data
this._viewabilityTuples.forEach(tuple => {
tuple.viewabilityHelper.resetViewableIndices();
});
}
this._scheduleCellsToRenderUpdate(); this._scheduleCellsToRenderUpdate();
} }