Summary:
- Properly inherit flow types from base components, including `defaultProps`
- template-ify the `Item` type as it flows from the `data` prop into `ItemComponent`

Note that for `SectionList` is is harder to do the `Item` typing because each section in the
`sections` array can have a different `Item` type, plus all the optional overrides...not sure how to
tackle that.

Reviewed By: yungsters

Differential Revision: D4557523

fbshipit-source-id: a0c5279fcdaabe6aab5fe11743a99c3715a44032
This commit is contained in:
Spencer Ahrens 2017-02-16 18:59:55 -08:00 коммит произвёл Facebook Github Bot
Родитель c529a06cb8
Коммит 63d3ea17a7
9 изменённых файлов: 319 добавлений и 78 удалений

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

@ -44,6 +44,7 @@ suppress_type=$FixMe
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(3[0-9]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native_oss[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(3[0-9]\\|1[0-9]\\|[1-2][0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native_oss[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
unsafe.enable_getters_and_setters=true

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

@ -108,7 +108,7 @@ class FlatListExample extends React.PureComponent {
key={(this.state.horizontal ? 'h' : 'v') + (this.state.fixedHeight ? 'f' : 'd')}
legacyImplementation={false}
numColumns={1}
onRefresh={() => alert('onRefresh: nothing to refresh :P')}
onRefresh={this._onRefresh}
onViewableItemsChanged={this._onViewableItemsChanged}
ref={this._captureRef}
refreshing={false}
@ -121,6 +121,7 @@ class FlatListExample extends React.PureComponent {
_getItemLayout = (data: any, index: number) => {
return getItemLayout(data, index, this.state.horizontal);
};
_onRefresh = () => alert('onRefresh: nothing to refresh :P');
_renderItemComponent = ({item}) => {
return (
<ItemComponent
@ -154,7 +155,7 @@ class FlatListExample extends React.PureComponent {
_pressItem = (key: number) => {
pressItem(this, key);
};
_listRef: FlatList;
_listRef: FlatList<*>;
}

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

@ -41,22 +41,23 @@ const invariant = require('invariant');
import type {StyleObj} from 'StyleSheetTypes';
import type {Viewable} from 'ViewabilityHelper';
import type {Props as VirtualizedListProps} from 'VirtualizedList';
type Item = any;
type RequiredProps = {
type RequiredProps<ItemT> = {
/**
* Note this can be a normal class component, or a functional component, such as a render method
* on your main component.
*/
ItemComponent: ReactClass<{item: Item, index: number}>,
ItemComponent: ReactClass<{item: ItemT, index: number}>,
/**
* For simplicity, data is just a plain array. If you want to use something else, like an
* immutable list, use the underlying `VirtualizedList` directly.
*/
data: ?Array<Item>,
data: ?Array<ItemT>,
};
type OptionalProps = {
type OptionalProps<ItemT> = {
/**
* Rendered at the bottom of all the items.
*/
@ -79,7 +80,7 @@ type OptionalProps = {
* Remember to include separator length (height or width) in your offset calculation if you
* specify `SeparatorComponent`.
*/
getItemLayout?: (data: ?Array<Item>, index: number) =>
getItemLayout?: (data: ?Array<ItemT>, index: number) =>
{length: number, offset: number, index: number},
/**
* If true, renders items next to each other horizontally instead of stacked vertically.
@ -90,7 +91,7 @@ type OptionalProps = {
* and as the react key to track item re-ordering. The default extractor checks item.key, then
* falls back to using the index, like react does.
*/
keyExtractor: (item: Item, index: number) => string,
keyExtractor: (item: ItemT, index: number) => string,
/**
* 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.
@ -111,6 +112,7 @@ type OptionalProps = {
* `viewablePercentThreshold` prop.
*/
onViewableItemsChanged?: ?({viewableItems: Array<Viewable>, changed: Array<Viewable>}) => void,
legacyImplementation?: ?boolean,
/**
* Set this true while waiting for new data from a refresh.
*/
@ -123,11 +125,19 @@ type OptionalProps = {
* Optional optimization to minimize re-rendering items.
*/
shouldItemUpdate: (
prevProps: {item: Item, index: number},
nextProps: {item: Item, index: number}
prevProps: {item: ItemT, index: number},
nextProps: {item: ItemT, index: number}
) => boolean,
};
type Props = RequiredProps & OptionalProps; // plus props from the underlying implementation
type Props<ItemT> = RequiredProps<ItemT> & OptionalProps<ItemT> & VirtualizedListProps;
const defaultProps = {
...VirtualizedList.defaultProps,
getItem: undefined,
getItemCount: undefined,
numColumns: 1,
};
type DefaultProps = typeof defaultProps;
/**
* A performant interface for rendering simple, flat lists, supporting the most handy features:
@ -148,13 +158,9 @@ type Props = RequiredProps & OptionalProps; // plus props from the underlying im
* ItemComponent={({item}) => <Text>{item.key}</Text>}
* />
*/
class FlatList extends React.PureComponent {
static defaultProps = {
keyExtractor: VirtualizedList.defaultProps.keyExtractor,
numColumns: 1,
shouldItemUpdate: VirtualizedList.defaultProps.shouldItemUpdate,
};
props: Props;
class FlatList<ItemT> extends React.PureComponent<DefaultProps, Props<ItemT>, void> {
static defaultProps: DefaultProps = defaultProps;
props: Props<ItemT>;
/**
* Scrolls to the end of the content. May be janky without getItemLayout prop.
*/
@ -191,7 +197,7 @@ class FlatList extends React.PureComponent {
this._checkProps(this.props);
}
componentWillReceiveProps(nextProps: Props) {
componentWillReceiveProps(nextProps: Props<ItemT>) {
this._checkProps(nextProps);
}
@ -200,7 +206,7 @@ class FlatList extends React.PureComponent {
_captureRef = (ref) => { this._listRef = ref; };
_checkProps(props: Props) {
_checkProps(props: Props<ItemT>) {
const {
getItem,
getItemCount,
@ -229,7 +235,7 @@ class FlatList extends React.PureComponent {
}
}
_getItem = (data: Array<Item>, index: number): Item | Array<Item> => {
_getItem = (data: Array<ItemT>, index: number): ItemT | Array<ItemT> => {
const {numColumns} = this.props;
if (numColumns > 1) {
const ret = [];
@ -243,13 +249,19 @@ class FlatList extends React.PureComponent {
}
};
_getItemCount = (data: Array<Item>): number => {
_getItemCount = (data: Array<ItemT>): number => {
return Math.floor(data.length / this.props.numColumns);
};
_keyExtractor = (items: Item | Array<Item>, index: number): string => {
_keyExtractor = (items: ItemT | Array<ItemT>, index: number): string => {
const {keyExtractor, numColumns} = this.props;
if (numColumns > 1) {
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((it, kk) => keyExtractor(it, index * numColumns + kk)).join(':');
} else {
return keyExtractor(items, index);

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

@ -49,7 +49,7 @@ type NormalProps = {
// Provide either `items` or `sections`
items?: ?Array<Item>, // By default, an Item is assumed to be {key: string}
sections?: ?Array<{key: string, items: Array<Item>}>,
sections?: ?Array<{key: string, data: Array<Item>}>,
/**
* If provided, a standard RefreshControl will be added for "Pull to Refresh" functionality. Make
@ -146,7 +146,7 @@ class MetroListView extends React.Component {
const sections = {};
props.sections.forEach((sectionIn, ii) => {
const sectionID = 's' + ii;
sections[sectionID] = sectionIn.itemData;
sections[sectionID] = sectionIn.data;
sectionHeaderData[sectionID] = sectionIn;
});
return {

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

@ -37,19 +37,19 @@ const React = require('React');
const VirtualizedSectionList = require('VirtualizedSectionList');
import type {Viewable} from 'ViewabilityHelper';
import type {Props as VirtualizedSectionListProps} from 'VirtualizedSectionList';
type Item = any;
type SectionItem = any;
type SectionBase = {
type SectionBase<SectionItemT> = {
// Must be provided directly on each section.
data: Array<SectionItem>,
data: Array<SectionItemT>,
key: string,
// Optional props will override list-wide props just for this section.
ItemComponent?: ?ReactClass<{item: SectionItem, index: number}>,
ItemComponent?: ?ReactClass<{item: SectionItemT, index: number}>,
SeparatorComponent?: ?ReactClass<*>,
keyExtractor?: (item: SectionItem) => string,
keyExtractor?: (item: SectionItemT) => string,
// TODO: support more optional/override props
// FooterComponent?: ?ReactClass<*>,
@ -57,15 +57,15 @@ type SectionBase = {
// onViewableItemsChanged?: ({viewableItems: Array<Viewable>, changed: Array<Viewable>}) => void,
// TODO: support recursive sections
// SectionHeaderComponent?: ?ReactClass<{section: SectionBase}>,
// SectionHeaderComponent?: ?ReactClass<{section: SectionBase<*>}>,
// sections?: ?Array<Section>;
};
type RequiredProps<SectionT: SectionBase> = {
type RequiredProps<SectionT: SectionBase<*>> = {
sections: Array<SectionT>,
};
type OptionalProps<SectionT: SectionBase> = {
type OptionalProps<SectionT: SectionBase<*>> = {
/**
* Rendered after the last item in the last section.
*/
@ -73,7 +73,7 @@ type OptionalProps<SectionT: SectionBase> = {
/**
* Default renderer for every item in every section.
*/
ItemComponent?: ?ReactClass<{item: Item, index: number}>,
ItemComponent: ReactClass<{item: Item, index: number}>,
/**
* Rendered at the top of each section. In the future, a sticky option will be added.
*/
@ -93,8 +93,8 @@ type OptionalProps<SectionT: SectionBase> = {
* stored outside of the recursive `ItemComponent` instance tree.
*/
enableVirtualization?: ?boolean,
keyExtractor?: (item: Item) => string,
onEndReached?: ({distanceFromEnd: number}) => void,
keyExtractor: (item: Item, index: number) => string,
onEndReached?: ?({distanceFromEnd: number}) => void,
/**
* If provided, a standard RefreshControl will be added for "Pull to Refresh" functionality. Make
* sure to also set the `refreshing` prop correctly.
@ -104,21 +104,25 @@ type OptionalProps<SectionT: SectionBase> = {
* Called when the viewability of rows changes, as defined by the
* `viewablePercentThreshold` prop.
*/
onViewableItemsChanged?: ({viewableItems: Array<Viewable>, changed: Array<Viewable>}) => void,
onViewableItemsChanged?: ?({viewableItems: Array<Viewable>, changed: Array<Viewable>}) => void,
/**
* Set this true while waiting for new data from a refresh.
*/
refreshing?: boolean,
refreshing?: ?boolean,
/**
* This is an optional optimization to minimize re-rendering items.
*/
shouldItemUpdate?: (
shouldItemUpdate: (
prevProps: {item: Item, index: number},
nextProps: {item: Item, index: number}
) => boolean,
};
type Props<SectionT> = RequiredProps<SectionT> & OptionalProps<SectionT>;
type Props<SectionT> = RequiredProps<SectionT>
& OptionalProps<SectionT>
& VirtualizedSectionListProps<SectionT>;
type DefaultProps = typeof VirtualizedSectionList.defaultProps;
/**
* A performant interface for rendering sectioned lists, supporting the most handy features:
@ -132,8 +136,11 @@ type Props<SectionT> = RequiredProps<SectionT> & OptionalProps<SectionT>;
*
* If you don't need section support and want a simpler interface, use FlatList.
*/
class SectionList<SectionT: SectionBase> extends React.Component<void, Props<SectionT>, void> {
class SectionList<SectionT: SectionBase<*>>
extends React.PureComponent<DefaultProps, Props<SectionT>, *>
{
props: Props<SectionT>;
static defaultProps: DefaultProps = VirtualizedSectionList.defaultProps;
render() {
if (this.props.legacyImplementation) {

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

@ -68,7 +68,7 @@ type RequiredProps = {
* The default accessor functions assume this is an Array<{key: string}> but you can override
* getItem, getItemCount, and keyExtractor to handle any type of index-based data.
*/
data: any,
data?: any,
};
type OptionalProps = {
FooterComponent?: ?ReactClass<*>,
@ -89,12 +89,12 @@ type OptionalProps = {
getItemCount: (items: any) => number,
getItemLayout?: (items: any, index: number) =>
{length: number, offset: number, index: number}, // e.g. height, y
horizontal: boolean,
horizontal?: ?boolean,
initialNumToRender: number,
keyExtractor: (item: Item, index: number) => string,
maxToRenderPerBatch: number,
onEndReached: ({distanceFromEnd: number}) => void,
onEndReachedThreshold: number, // units of visible length
onEndReached?: ?({distanceFromEnd: number}) => void,
onEndReachedThreshold?: ?number, // units of visible length
onLayout?: ?Function,
/**
* If provided, a standard RefreshControl will be added for "Pull to Refresh" functionality. Make
@ -105,11 +105,11 @@ type OptionalProps = {
* Called when the viewability of rows changes, as defined by the
* `viewablePercentThreshold` prop.
*/
onViewableItemsChanged?: ({viewableItems: Array<Viewable>, changed: Array<Viewable>}) => void,
onViewableItemsChanged?: ?({viewableItems: Array<Viewable>, changed: Array<Viewable>}) => void,
/**
* Set this true while waiting for new data from a refresh.
*/
refreshing?: boolean,
refreshing?: ?boolean,
removeClippedSubviews?: boolean,
renderScrollComponent: (props: Object) => React.Element<*>,
shouldItemUpdate: (
@ -126,11 +126,11 @@ type OptionalProps = {
viewablePercentThreshold: number,
windowSize: number, // units of visible length
};
type Props = RequiredProps & OptionalProps;
export type Props = RequiredProps & OptionalProps;
let _usedIndexForKey = false;
class VirtualizedList extends React.PureComponent {
class VirtualizedList extends React.PureComponent<OptionalProps, Props, *> {
props: Props;
// scrollToEnd may be janky without getItemLayout prop
@ -182,7 +182,7 @@ class VirtualizedList extends React.PureComponent {
);
}
static defaultProps: OptionalProps = {
static defaultProps = {
disableVirtualization: false,
getItem: (data: any, index: number) => data[index],
getItemCount: (data: any) => data ? data.length : 0,
@ -390,7 +390,12 @@ class VirtualizedList extends React.PureComponent {
_onCellLayout = (e, cellKey, index) => {
const layout = e.nativeEvent.layout;
const next = {offset: this._selectOffset(layout), length: this._selectLength(layout), index, inLayout: true};
const next = {
offset: this._selectOffset(layout),
length: this._selectLength(layout),
index,
inLayout: true,
};
const curr = this._frames[cellKey];
if (!curr ||
next.offset !== curr.offset ||

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

@ -40,11 +40,12 @@ const invariant = require('invariant');
const warning = require('warning');
import type {Viewable} from 'ViewabilityHelper';
import type {Props as VirtualizedListProps} from 'VirtualizedList';
type Item = any;
type SectionItem = any;
type Section = {
type SectionBase = {
// Must be provided directly on each section.
data: Array<SectionItem>,
key: string,
@ -60,17 +61,35 @@ type Section = {
// onViewableItemsChanged?: ({viewableItems: Array<Viewable>, changed: Array<Viewable>}) => void,
// TODO: support recursive sections
// SectionHeaderComponent?: ?ReactClass<{section: Section}>,
// SectionHeaderComponent?: ?ReactClass<{section: SectionBase}>,
// sections?: ?Array<Section>;
}
type RequiredProps = {
sections: Array<Section>,
};
type OptionalProps = {
ItemComponent?: ?ReactClass<{item: Item, index: number}>,
SectionHeaderComponent?: ?ReactClass<{section: Section}>,
type RequiredProps<SectionT: SectionBase> = {
sections: Array<SectionT>,
};
type OptionalProps<SectionT: SectionBase> = {
/**
* Rendered after the last item in the last section.
*/
FooterComponent?: ?ReactClass<*>,
/**
* Default renderer for every item in every section.
*/
ItemComponent: ReactClass<{item: Item, index: number}>,
/**
* Rendered at the top of each section. In the future, a sticky option will be added.
*/
SectionHeaderComponent?: ?ReactClass<{section: SectionT}>,
/**
* Rendered at the bottom of every Section, except the very last one, in place of the normal
* SeparatorComponent.
*/
SectionSeparatorComponent?: ?ReactClass<*>,
/**
* Rendered at the bottom of every Item except the very last one in the last section.
*/
SeparatorComponent?: ?ReactClass<*>,
/**
* Warning: Virtualization can drastically improve memory consumption for long lists, but trashes
@ -78,42 +97,65 @@ type OptionalProps = {
* stored outside of the recursive `ItemComponent` instance tree.
*/
enableVirtualization?: ?boolean,
horizontal?: ?boolean,
keyExtractor?: (item: Item, index: number) => string,
onEndReached?: ({distanceFromEnd: number}) => void,
keyExtractor: (item: Item, index: number) => string,
onEndReached?: ?({distanceFromEnd: number}) => void,
/**
* If provided, a standard RefreshControl will be added for "Pull to Refresh" functionality. Make
* sure to also set the `refreshing` prop correctly.
*/
onRefresh?: ?Function,
/**
* Called when the viewability of rows changes, as defined by the
* `viewablePercentThreshold` prop. Called for all items from all sections.
* `viewablePercentThreshold` prop.
*/
onViewableItemsChanged?: ({viewableItems: Array<Viewable>, changed: Array<Viewable>}) => void,
onViewableItemsChanged?: ?({viewableItems: Array<Viewable>, changed: Array<Viewable>}) => void,
/**
* Set this true while waiting for new data from a refresh.
*/
refreshing?: ?boolean,
/**
* This is an optional optimization to minimize re-rendering items.
*/
shouldItemUpdate: (
prevProps: {item: Item, index: number},
nextProps: {item: Item, index: number}
) => boolean,
};
type Props = RequiredProps & OptionalProps;
export type Props<SectionT> =
RequiredProps<SectionT> &
OptionalProps<SectionT> &
VirtualizedListProps;
type DefaultProps = (typeof VirtualizedList.defaultProps) & {data: Array<Item>};
type State = {childProps: VirtualizedListProps};
/**
* Right now this just flattens everything into one list and uses VirtualizedList under the
* hood. The only operation that might not scale well is concatting the data arrays of all the
* sections when new props are received, which should be plenty fast for up to ~10,000 items.
*/
class VirtualizedSectionList extends React.PureComponent {
props: Props;
class VirtualizedSectionList<SectionT: SectionBase>
extends React.PureComponent<DefaultProps, Props<SectionT>, State>
{
props: Props<SectionT>;
state: {
childProps: Object,
};
state: State;
static defaultProps: OptionalProps = {
keyExtractor: (item: Item, index: number) => item.key || String(index),
static defaultProps: DefaultProps = {
...VirtualizedList.defaultProps,
data: [],
};
_keyExtractor = (item: Item, index: number) => {
const info = this._subExtractor(index);
return info && info.key;
return (info && info.key) || String(index);
};
_subExtractor(
index: number,
): ?{
section: Section,
section: SectionT,
key: string, // Key of the section or combined key for section + item
index: ?number, // Relative index within the section
} {
@ -221,9 +263,10 @@ class VirtualizedSectionList extends React.PureComponent {
return true;
}
}
return false;
}
_computeState(props: Props) {
_computeState(props: Props<SectionT>): State {
const itemCount = props.sections.reduce((v, section) => v + section.data.length + 1, 0);
return {
childProps: {
@ -242,7 +285,7 @@ class VirtualizedSectionList extends React.PureComponent {
};
}
constructor(props: Props, context: Object) {
constructor(props: Props<SectionT>, context: Object) {
super(props, context);
warning(
!props.stickySectionHeadersEnabled,
@ -251,7 +294,7 @@ class VirtualizedSectionList extends React.PureComponent {
this.state = this._computeState(props);
}
componentWillReceiveProps(nextProps: Props) {
componentWillReceiveProps(nextProps: Props<SectionT>) {
this.setState(this._computeState(nextProps));
}

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

@ -0,0 +1,77 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @flow
*/
'use strict';
const FlatList = require('FlatList');
const React = require('react');
class MyListItem extends React.Component {
props: {
item: {
title: string,
},
};
render() {
return <span />;
}
}
module.exports = {
testBadDataWithTypicalItemComponent(): React.Element<*> {
// $FlowExpectedError - bad title type 6, should be string
const data = [{
title: 6,
key: 1,
}];
return <FlatList ItemComponent={MyListItem} data={data} />;
},
testMissingFieldWithTypicalItemComponent(): React.Element<*> {
const data = [{
key: 1,
}];
// $FlowExpectedError - missing title
return <FlatList ItemComponent={MyListItem} data={data} />;
},
testGoodDataWithGoodCustomItemComponentFunction() {
const data = [{
widgetCount: 3,
key: 1,
}];
return (
<FlatList
ItemComponent={(props: {widgetCount: number}): React.Element<*> =>
<MyListItem item={{title: props.widgetCount + ' Widgets'}} />
}
data={data}
/>
);
},
testBadNonInheritedDefaultProp(): React.Element<*> {
const data = [];
// $FlowExpectedError - bad numColumns type "lots"
return <FlatList ItemComponent={MyListItem} data={data} numColumns="lots" />;
},
testBadInheritedDefaultProp(): React.Element<*> {
const data = [];
// $FlowExpectedError - bad windowSize type "big"
return <FlatList ItemComponent={MyListItem} data={data} windowSize="big" />;
},
testMissingData(): React.Element<*> {
// $FlowExpectedError - missing `data` prop
return <FlatList ItemComponent={MyListItem} />;
},
};

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

@ -0,0 +1,95 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @flow
*/
'use strict';
const React = require('react');
const SectionList = require('SectionList');
class MyListItem extends React.Component {
props: {
item: {
title: string,
},
};
render() {
return <span />;
}
}
class MyHeader extends React.Component {
props: {
section: {
fooNumber: number,
}
};
render() {
return <span />;
}
}
module.exports = {
testGoodDataWithGoodCustomItemComponentFunction() {
const sections = [{
key: 'a', data: [{
widgetCount: 3,
key: 1,
}],
}];
return (
<SectionList
ItemComponent={(props: {widgetCount: number}): React.Element<*> =>
<MyListItem item={{title: props.widgetCount + ' Widgets'}} />
}
sections={sections}
/>
);
},
testBadInheritedDefaultProp(): React.Element<*> {
const sections = [];
// $FlowExpectedError - bad windowSize type "big"
return <SectionList ItemComponent={MyListItem} sections={sections} windowSize="big" />;
},
testMissingData(): React.Element<*> {
// $FlowExpectedError - missing `sections` prop
return <SectionList ItemComponent={MyListItem} />;
},
testBadSectionsShape(): React.Element<*> {
const sections = [{
key: 'a', items: [{
title: 'foo',
key: 1,
}],
}];
// $FlowExpectedError - section missing `data` field
return <SectionList ItemComponent={MyListItem} sections={sections} />;
},
testBadSectionsMetadata(): React.Element<*> {
// $FlowExpectedError - section has bad meta data `fooNumber` field of type string
const sections = [{
key: 'a', fooNumber: 'string', data: [{
title: 'foo',
key: 1,
}],
}];
return (
<SectionList
SectionHeaderComponent={MyHeader}
ItemComponent={MyListItem}
sections={sections}
/>
);
},
};