Remove UNSAFE_componentWillReceiveProps

Summary:
Changelog:
[General][Fixed] Remove UNSAFE_componentWillReceiveProps from VirtualizedSectionList

Reviewed By: nadiia

Differential Revision: D26381837

fbshipit-source-id: b029c82e4090369c76f303e71a3c9158e34ad82e
This commit is contained in:
Luna Wei 2021-02-12 14:46:34 -08:00 коммит произвёл Facebook GitHub Bot
Родитель 4384fb266b
Коммит 4e6d33a112
3 изменённых файлов: 69 добавлений и 89 удалений

Просмотреть файл

@ -162,58 +162,55 @@ class VirtualizedSectionList<
return this._listRef;
}
constructor(props: Props<SectionT>, context: Object) {
super(props, context);
this.state = this._computeState(props);
}
UNSAFE_componentWillReceiveProps(nextProps: Props<SectionT>) {
this.setState(this._computeState(nextProps));
}
_computeState(props: Props<SectionT>): State {
const offset = props.ListHeaderComponent ? 1 : 0;
const stickyHeaderIndices = [];
const itemCount = props.sections
? props.sections.reduce((v, section) => {
stickyHeaderIndices.push(v + offset);
return v + props.getItemCount(section.data) + 2; // Add two for the section header and footer.
}, 0)
: 0;
render(): React.Node {
const {
ItemSeparatorComponent, // don't pass through, rendered with renderItem
SectionSeparatorComponent,
renderItem,
renderItem: _renderItem,
renderSectionFooter,
renderSectionHeader,
sections: _sections,
stickySectionHeadersEnabled,
...restProps
} = props;
...passThroughProps
} = this.props;
return {
childProps: {
...restProps,
renderItem: this._renderItem,
ItemSeparatorComponent: undefined, // Rendered with renderItem
data: props.sections,
getItemCount: () => itemCount,
// $FlowFixMe
getItem: (sections, index) => this._getItem(props, sections, index),
keyExtractor: this._keyExtractor,
onViewableItemsChanged: props.onViewableItemsChanged
? this._onViewableItemsChanged
: undefined,
stickyHeaderIndices: props.stickySectionHeadersEnabled
? stickyHeaderIndices
: undefined,
},
};
}
const listHeaderOffset = this.props.ListHeaderComponent ? 1 : 0;
const stickyHeaderIndices = this.props.stickySectionHeadersEnabled
? []
: undefined;
let itemCount = 0;
for (const section of this.props.sections) {
// Track the section header indices
if (stickyHeaderIndices != null) {
stickyHeaderIndices.push(itemCount + listHeaderOffset);
}
// Add two for the section header and footer.
itemCount += 2;
itemCount += this.props.getItemCount(section.data);
}
const renderItem = this._renderItem(itemCount);
render(): React.Node {
return (
<VirtualizedList {...this.state.childProps} ref={this._captureRef} />
<VirtualizedList
{...passThroughProps}
keyExtractor={this._keyExtractor}
stickyHeaderIndices={stickyHeaderIndices}
renderItem={renderItem}
data={this.props.sections}
getItem={(sections, index) =>
this._getItem(this.props, sections, index)
}
getItemCount={() => itemCount}
onViewableItemsChanged={
this.props.onViewableItemsChanged
? this._onViewableItemsChanged
: undefined
}
ref={this._captureRef}
/>
);
}
@ -344,7 +341,14 @@ class VirtualizedSectionList<
}
};
_renderItem = ({item, index}: {item: Item, index: number, ...}) => {
_renderItem = (listItemCount: number) => ({
item,
index,
}: {
item: Item,
index: number,
...
}) => {
const info = this._subExtractor(index);
if (!info) {
return null;
@ -361,7 +365,11 @@ class VirtualizedSectionList<
}
} else {
const renderItem = info.section.renderItem || this.props.renderItem;
const SeparatorComponent = this._getSeparatorComponent(index, info);
const SeparatorComponent = this._getSeparatorComponent(
index,
info,
listItemCount,
);
invariant(renderItem, 'no renderItem!');
return (
<ItemWithSeparator
@ -397,6 +405,7 @@ class VirtualizedSectionList<
_getSeparatorComponent(
index: number,
info?: ?Object,
listItemCount: number,
): ?React.ComponentType<any> {
info = info || this._subExtractor(index);
if (!info) {
@ -405,7 +414,7 @@ class VirtualizedSectionList<
const ItemSeparatorComponent =
info.section.ItemSeparatorComponent || this.props.ItemSeparatorComponent;
const {SectionSeparatorComponent} = this.props;
const isLastItemInList = index === this.state.childProps.getItemCount() - 1;
const isLastItemInList = index === listItemCount - 1;
const isLastItemInSection =
info.index === this.props.getItemCount(info.section.data) - 1;
if (SectionSeparatorComponent && isLastItemInSection) {

Просмотреть файл

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow
* @emails oncall+react_native
*/
@ -42,18 +43,6 @@ describe('VirtualizedSectionList', () => {
expect(component).toMatchSnapshot();
});
it('renders null list', () => {
const component = ReactTestRenderer.create(
<VirtualizedSectionList
sections={undefined}
renderItem={({item}) => <item value={item.key} />}
getItem={(data, key) => data[key]}
getItemCount={data => 0}
/>,
);
expect(component).toMatchSnapshot();
});
it('renders empty list with empty component', () => {
const component = ReactTestRenderer.create(
<VirtualizedSectionList
@ -97,7 +86,11 @@ describe('VirtualizedSectionList', () => {
]}
getItem={(data, key) => data[key]}
getItemCount={data => data.length}
getItemLayout={({index}) => ({length: 50, offset: index * 50})}
getItemLayout={({index}) => ({
index: -1,
length: 50,
offset: index * 50,
})}
inverted={true}
keyExtractor={(item, index) => item.id}
onRefresh={jest.fn()}
@ -185,7 +178,11 @@ describe('VirtualizedSectionList', () => {
);
const instance = component.getInstance();
const spy = jest.fn();
// $FlowFixMe[incompatible-use] wrong types
// $FlowFixMe[prop-missing] wrong types
instance._listRef.scrollToIndex = spy;
return {
instance,
spy,
@ -199,7 +196,8 @@ describe('VirtualizedSectionList', () => {
const viewOffset = 25;
instance.scrollToLocation({
// $FlowFixMe scrollToLocation isn't on instance
instance?.scrollToLocation({
sectionIndex: 0,
itemIndex: 1,
viewOffset,
@ -249,8 +247,8 @@ describe('VirtualizedSectionList', () => {
'given sectionIndex, itemIndex and viewOffset, scrollToIndex is called with correct params',
(scrollToLocationParams, expected) => {
const {instance, spy} = createVirtualizedSectionList();
instance.scrollToLocation(scrollToLocationParams);
// $FlowFixMe[prop-missing] scrollToLocation not on instance
instance?.scrollToLocation(scrollToLocationParams);
expect(spy).toHaveBeenCalledWith(expected);
},
);

Просмотреть файл

@ -1015,33 +1015,6 @@ exports[`VirtualizedSectionList renders list with empty component 1`] = `
</RCTScrollView>
`;
exports[`VirtualizedSectionList renders null list 1`] = `
<RCTScrollView
disableVirtualization={false}
getItem={[Function]}
getItemCount={[Function]}
horizontal={false}
initialNumToRender={10}
keyExtractor={[Function]}
maxToRenderPerBatch={10}
onContentSizeChange={[Function]}
onEndReachedThreshold={2}
onLayout={[Function]}
onMomentumScrollBegin={[Function]}
onMomentumScrollEnd={[Function]}
onScroll={[Function]}
onScrollBeginDrag={[Function]}
onScrollEndDrag={[Function]}
renderItem={[Function]}
scrollEventThrottle={50}
stickyHeaderIndices={Array []}
updateCellsBatchingPeriod={50}
windowSize={21}
>
<View />
</RCTScrollView>
`;
exports[`VirtualizedSectionList renders simple list 1`] = `
<RCTScrollView
data={