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:
Родитель
4384fb266b
Коммит
4e6d33a112
|
@ -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={
|
||||
|
|
Загрузка…
Ссылка в новой задаче