mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
RN: Minor Flow Cleanup in FlatList
Summary: Cleans up a few minor Flow suppression comments in `FlatList`. This reveals a new Flow error that is the result of `FlatList`'s props object being inexact whereas `VirtualizedList`'s props object is exact. For now, I introduce another -- but more specific -- Flow suppression for that type error. The code changes should not have any consequential behavior change. Changelog: [Internal] Reviewed By: NickGerleman Differential Revision: D38646228 fbshipit-source-id: f4f9b0ad95323157ff1519353b38e8486adc841d
This commit is contained in:
committed by
Facebook GitHub Bot
parent
23429330a6
commit
459b25ce43
+46
-54
@@ -523,30 +523,26 @@ class FlatList<ItemT> extends React.PureComponent<Props<ItemT>, void> {
|
||||
}
|
||||
};
|
||||
|
||||
// $FlowFixMe[missing-local-annot]
|
||||
_keyExtractor = (items: ItemT | Array<ItemT>, index: number) => {
|
||||
_keyExtractor = (items: ItemT | Array<ItemT>, index: number): string => {
|
||||
const numColumns = numColumnsOrDefault(this.props.numColumns);
|
||||
const keyExtractor = this.props.keyExtractor ?? defaultKeyExtractor;
|
||||
|
||||
if (numColumns > 1) {
|
||||
if (Array.isArray(items)) {
|
||||
return items
|
||||
.map((item, kk) =>
|
||||
keyExtractor(((item: $FlowFixMe): ItemT), index * numColumns + kk),
|
||||
)
|
||||
.join(':');
|
||||
} else {
|
||||
invariant(
|
||||
Array.isArray(items),
|
||||
'FlatList: Encountered internal consistency error, expected each item to consist of an ' +
|
||||
'array with 1-%s columns; instead, received a single item.',
|
||||
numColumns,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// $FlowFixMe[incompatible-call] Can't call keyExtractor with an array
|
||||
return keyExtractor(items, index);
|
||||
invariant(
|
||||
Array.isArray(items),
|
||||
'FlatList: Encountered internal consistency error, expected each item to consist of an ' +
|
||||
'array with 1-%s columns; instead, received a single item.',
|
||||
numColumns,
|
||||
);
|
||||
return items
|
||||
.map((item, kk) =>
|
||||
keyExtractor(((item: $FlowFixMe): ItemT), index * numColumns + kk),
|
||||
)
|
||||
.join(':');
|
||||
}
|
||||
|
||||
// $FlowFixMe[incompatible-call] Can't call keyExtractor with an array
|
||||
return keyExtractor(items, index);
|
||||
};
|
||||
|
||||
_pushMultiColumnViewable(arr: Array<ViewToken>, v: ViewToken): void {
|
||||
@@ -599,11 +595,7 @@ class FlatList<ItemT> extends React.PureComponent<Props<ItemT>, void> {
|
||||
) => {
|
||||
const cols = numColumnsOrDefault(numColumns);
|
||||
|
||||
let virtualizedListRenderKey = ListItemComponent
|
||||
? 'ListItemComponent'
|
||||
: 'renderItem';
|
||||
|
||||
const renderer = (props: RenderItemProps<ItemT>): React.Node => {
|
||||
const render = (props: RenderItemProps<ItemT>): React.Node => {
|
||||
if (ListItemComponent) {
|
||||
// $FlowFixMe[not-a-component] Component isn't valid
|
||||
// $FlowFixMe[incompatible-type-arg] Component isn't valid
|
||||
@@ -617,37 +609,36 @@ class FlatList<ItemT> extends React.PureComponent<Props<ItemT>, void> {
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
/* $FlowFixMe[invalid-computed-prop] (>=0.111.0 site=react_native_fb)
|
||||
* This comment suppresses an error found when Flow v0.111 was deployed.
|
||||
* To see the error, delete this comment and run Flow. */
|
||||
[virtualizedListRenderKey]: (info: RenderItemProps<ItemT>) => {
|
||||
if (cols > 1) {
|
||||
const {item, index} = info;
|
||||
invariant(
|
||||
Array.isArray(item),
|
||||
'Expected array of items with numColumns > 1',
|
||||
);
|
||||
return (
|
||||
<View style={StyleSheet.compose(styles.row, columnWrapperStyle)}>
|
||||
{item.map((it, kk) => {
|
||||
const element = renderer({
|
||||
// $FlowFixMe[incompatible-call]
|
||||
item: it,
|
||||
index: index * cols + kk,
|
||||
separators: info.separators,
|
||||
});
|
||||
return element != null ? (
|
||||
<React.Fragment key={kk}>{element}</React.Fragment>
|
||||
) : null;
|
||||
})}
|
||||
</View>
|
||||
);
|
||||
} else {
|
||||
return renderer(info);
|
||||
}
|
||||
},
|
||||
const renderProp = (info: RenderItemProps<ItemT>) => {
|
||||
if (cols > 1) {
|
||||
const {item, index} = info;
|
||||
invariant(
|
||||
Array.isArray(item),
|
||||
'Expected array of items with numColumns > 1',
|
||||
);
|
||||
return (
|
||||
<View style={StyleSheet.compose(styles.row, columnWrapperStyle)}>
|
||||
{item.map((it, kk) => {
|
||||
const element = render({
|
||||
// $FlowFixMe[incompatible-call]
|
||||
item: it,
|
||||
index: index * cols + kk,
|
||||
separators: info.separators,
|
||||
});
|
||||
return element != null ? (
|
||||
<React.Fragment key={kk}>{element}</React.Fragment>
|
||||
) : null;
|
||||
})}
|
||||
</View>
|
||||
);
|
||||
} else {
|
||||
return render(info);
|
||||
}
|
||||
};
|
||||
|
||||
return ListItemComponent
|
||||
? {ListItemComponent: renderProp}
|
||||
: {renderItem: renderProp};
|
||||
};
|
||||
|
||||
// $FlowFixMe[missing-local-annot]
|
||||
@@ -665,6 +656,7 @@ class FlatList<ItemT> extends React.PureComponent<Props<ItemT>, void> {
|
||||
const renderer = strictMode ? this._memoizedRenderer : this._renderer;
|
||||
|
||||
return (
|
||||
// $FlowFixMe[incompatible-exact] - `restProps` (`Props`) is inexact.
|
||||
<VirtualizedList
|
||||
{...restProps}
|
||||
getItem={this._getItem}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
import type {AnimatedComponentType} from 'react-native/Libraries/Animated/createAnimatedComponent';
|
||||
import typeof FlatListType from 'react-native/Libraries/Lists/FlatList';
|
||||
import type {RenderItemProps} from 'react-native/Libraries/Lists/VirtualizedListProps';
|
||||
|
||||
import type {RNTesterModuleExample} from '../../types/RNTesterTypes';
|
||||
import * as React from 'react';
|
||||
@@ -94,7 +95,7 @@ class FlatListExample extends React.PureComponent<Props, State> {
|
||||
};
|
||||
|
||||
_onChangeScrollToIndex = (text: mixed) => {
|
||||
this._listRef.scrollToIndex({viewPosition: 0.5, index: Number(text)});
|
||||
this._listRef?.scrollToIndex({viewPosition: 0.5, index: Number(text)});
|
||||
};
|
||||
|
||||
// $FlowFixMe[missing-local-annot]
|
||||
@@ -111,7 +112,7 @@ class FlatListExample extends React.PureComponent<Props, State> {
|
||||
);
|
||||
|
||||
componentDidUpdate() {
|
||||
this._listRef.recordInteraction(); // e.g. flipping logViewable switch
|
||||
this._listRef?.recordInteraction(); // e.g. flipping logViewable switch
|
||||
}
|
||||
|
||||
_setBooleanValue: string => boolean => void = key => value =>
|
||||
@@ -270,7 +271,7 @@ class FlatListExample extends React.PureComponent<Props, State> {
|
||||
React.ElementConfig<FlatListType>,
|
||||
React.ElementRef<FlatListType>,
|
||||
>,
|
||||
>,
|
||||
> | null,
|
||||
) => {
|
||||
this._listRef = ref;
|
||||
};
|
||||
@@ -297,31 +298,25 @@ class FlatListExample extends React.PureComponent<Props, State> {
|
||||
_onRefresh = () => Alert.alert('onRefresh: nothing to refresh :P');
|
||||
// $FlowFixMe[missing-local-annot]
|
||||
_renderItemComponent = () => {
|
||||
const flatListPropKey = this.state.useFlatListItemComponent
|
||||
? 'ListItemComponent'
|
||||
: 'renderItem';
|
||||
|
||||
return {
|
||||
renderItem: undefined,
|
||||
/* $FlowFixMe[invalid-computed-prop] (>=0.111.0 site=react_native_fb)
|
||||
* This comment suppresses an error found when Flow v0.111 was deployed.
|
||||
* To see the error, delete this comment and run Flow. */
|
||||
/* $FlowFixMe[missing-local-annot] The type annotation(s) required by
|
||||
* Flow's LTI update could not be added via codemod */
|
||||
[flatListPropKey]: ({item, separators}) => {
|
||||
return (
|
||||
<ItemComponent
|
||||
item={item}
|
||||
horizontal={this.state.horizontal}
|
||||
fixedHeight={this.state.fixedHeight}
|
||||
onPress={this._onPressCallback()}
|
||||
onShowUnderlay={separators.highlight}
|
||||
onHideUnderlay={separators.unhighlight}
|
||||
textSelectable={this.state.textSelectable}
|
||||
/>
|
||||
);
|
||||
},
|
||||
const renderProp = ({item, separators}: RenderItemProps<Item>) => {
|
||||
return (
|
||||
<ItemComponent
|
||||
item={item}
|
||||
horizontal={this.state.horizontal}
|
||||
fixedHeight={this.state.fixedHeight}
|
||||
onPress={this._onPressCallback()}
|
||||
onShowUnderlay={separators.highlight}
|
||||
onHideUnderlay={separators.unhighlight}
|
||||
textSelectable={this.state.textSelectable}
|
||||
/>
|
||||
);
|
||||
};
|
||||
return this.state.useFlatListItemComponent
|
||||
? {
|
||||
renderItem: undefined,
|
||||
ListItemComponent: renderProp,
|
||||
}
|
||||
: {renderItem: renderProp};
|
||||
};
|
||||
// This is called when items change viewability by scrolling into or out of
|
||||
// the viewable area.
|
||||
@@ -346,7 +341,7 @@ class FlatListExample extends React.PureComponent<Props, State> {
|
||||
};
|
||||
|
||||
_pressItem = (key: string) => {
|
||||
this._listRef && this._listRef.recordInteraction();
|
||||
this._listRef?.recordInteraction();
|
||||
const index = Number(key);
|
||||
const itemState = pressItem(this.state.data[index]);
|
||||
this.setState(state => ({
|
||||
@@ -359,7 +354,7 @@ class FlatListExample extends React.PureComponent<Props, State> {
|
||||
}));
|
||||
};
|
||||
|
||||
_listRef: React.ElementRef<typeof Animated.FlatList>;
|
||||
_listRef: React.ElementRef<typeof Animated.FlatList> | null;
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
|
||||
Reference in New Issue
Block a user