diff --git a/Libraries/Lists/FlatList.js b/Libraries/Lists/FlatList.js index b9008a028a78ca..5e49715a8e7161 100644 --- a/Libraries/Lists/FlatList.js +++ b/Libraries/Lists/FlatList.js @@ -125,14 +125,39 @@ type OptionalProps = {| /** * Multiple columns can only be rendered with `horizontal={false}` and will zig-zag like a * `flexWrap` layout. Items should all be the same height - masonry layouts are not supported. + * + * The default value is 1. */ - numColumns: number, + numColumns?: number, + /** + * Note: may have bugs (missing content) in some circumstances - use at your own risk. + * + * This may improve scroll performance for large lists. + * + * The default value is true for Android. + */ + removeClippedSubviews?: boolean, /** * See `ScrollView` for flow type and further documentation. */ fadingEdgeLength?: ?number, |}; +/** + * Default Props Helper Functions + * Use the following helper functions for default values + */ + +// removeClippedSubviewsOrDefault(this.props.removeClippedSubviews) +function removeClippedSubviewsOrDefault(removeClippedSubviews: ?boolean) { + return removeClippedSubviews ?? Platform.OS === 'android'; +} + +// numColumnsOrDefault(this.props.numColumns) +function numColumnsOrDefault(numColumns: ?number) { + return numColumns ?? 1; +} + type FlatListProps = {| ...RequiredProps, ...OptionalProps, @@ -156,17 +181,6 @@ export type Props = { ... }; -const defaultProps = { - numColumns: 1, - /** - * Enabling this prop on Android greatly improves scrolling performance with no known issues. - * The alternative is that scrolling on Android is unusably bad. Enabling it on iOS has a few - * known issues. - */ - removeClippedSubviews: Platform.OS === 'android', -}; -export type DefaultProps = typeof defaultProps; - /** * A performant interface for rendering simple, flat lists, supporting the most handy features: * @@ -276,7 +290,6 @@ export type DefaultProps = typeof defaultProps; * Also inherits [ScrollView Props](docs/scrollview.html#props), unless it is nested in another FlatList of same orientation. */ class FlatList extends React.PureComponent, void> { - static defaultProps: DefaultProps = defaultProps; props: Props; /** * Scrolls to the end of the content. May be janky without `getItemLayout` prop. @@ -453,11 +466,11 @@ class FlatList extends React.PureComponent, void> { // $FlowFixMe[prop-missing] this prop doesn't exist, is only used for an invariant getItemCount, horizontal, - numColumns, columnWrapperStyle, onViewableItemsChanged, viewabilityConfigCallbackPairs, } = props; + const numColumns = numColumnsOrDefault(this.props.numColumns); invariant( !getItem && !getItemCount, 'FlatList does not support custom data formats.', @@ -478,7 +491,7 @@ class FlatList extends React.PureComponent, void> { } _getItem = (data: Array, index: number) => { - const {numColumns} = this.props; + const numColumns = numColumnsOrDefault(this.props.numColumns); if (numColumns > 1) { const ret = []; for (let kk = 0; kk < numColumns; kk++) { @@ -495,7 +508,7 @@ class FlatList extends React.PureComponent, void> { _getItemCount = (data: ?Array): number => { if (data) { - const {numColumns} = this.props; + const numColumns = numColumnsOrDefault(this.props.numColumns); return numColumns > 1 ? Math.ceil(data.length / numColumns) : data.length; } else { return 0; @@ -503,7 +516,7 @@ class FlatList extends React.PureComponent, void> { }; _keyExtractor = (items: ItemT | Array, index: number) => { - const {numColumns} = this.props; + const numColumns = numColumnsOrDefault(this.props.numColumns); const keyExtractor = this.props.keyExtractor ?? defaultKeyExtractor; if (numColumns > 1) { @@ -528,7 +541,7 @@ class FlatList extends React.PureComponent, void> { }; _pushMultiColumnViewable(arr: Array, v: ViewToken): void { - const {numColumns} = this.props; + const numColumns = numColumnsOrDefault(this.props.numColumns); const keyExtractor = this.props.keyExtractor ?? defaultKeyExtractor; v.item.forEach((item, ii) => { invariant(v.index != null, 'Missing index!'); @@ -549,7 +562,7 @@ class FlatList extends React.PureComponent, void> { changed: Array, ... }) => { - const {numColumns} = this.props; + const numColumns = numColumnsOrDefault(this.props.numColumns); if (onViewableItemsChanged) { if (numColumns > 1) { const changed = []; @@ -567,12 +580,8 @@ class FlatList extends React.PureComponent, void> { } _renderer = () => { - const { - ListItemComponent, - renderItem, - numColumns, - columnWrapperStyle, - } = this.props; + const {ListItemComponent, renderItem, columnWrapperStyle} = this.props; + const numColumns = numColumnsOrDefault(this.props.numColumns); let virtualizedListRenderKey = ListItemComponent ? 'ListItemComponent' @@ -625,7 +634,12 @@ class FlatList extends React.PureComponent, void> { }; render(): React.Node { - const {numColumns, columnWrapperStyle, ...restProps} = this.props; + const { + numColumns, + columnWrapperStyle, + removeClippedSubviews: _removeClippedSubviews, + ...restProps + } = this.props; return ( extends React.PureComponent, void> { keyExtractor={this._keyExtractor} ref={this._captureRef} viewabilityConfigCallbackPairs={this._virtualizedListPairs} + removeClippedSubviews={removeClippedSubviewsOrDefault( + _removeClippedSubviews, + )} {...this._renderer()} /> );