Improve docs

Reviewed By: hramos

Differential Revision: D4649351

fbshipit-source-id: 06cbd735bdb51b6d9d4997a348cbc191193485aa
This commit is contained in:
Spencer Ahrens 2017-03-03 13:14:04 -08:00 committed by Facebook Github Bot
parent 8174a0dc08
commit 2022b1eee6
4 changed files with 108 additions and 47 deletions

View File

@ -77,7 +77,9 @@ class FlatListExample extends React.PureComponent {
}
render() {
const filterRegex = new RegExp(String(this.state.filterText), 'i');
const filter = (item) => (filterRegex.test(item.text) || filterRegex.test(item.title));
const filter = (item) => (
filterRegex.test(item.text) || filterRegex.test(item.title)
);
const filteredData = this.state.data.filter(filter);
return (
<UIExplorerPage
@ -112,9 +114,14 @@ class FlatListExample extends React.PureComponent {
data={filteredData}
debug={this.state.debug}
disableVirtualization={!this.state.virtualized}
getItemLayout={this.state.fixedHeight ? this._getItemLayout : undefined}
getItemLayout={this.state.fixedHeight ?
this._getItemLayout :
undefined
}
horizontal={this.state.horizontal}
key={(this.state.horizontal ? 'h' : 'v') + (this.state.fixedHeight ? 'f' : 'd')}
key={(this.state.horizontal ? 'h' : 'v') +
(this.state.fixedHeight ? 'f' : 'd')
}
legacyImplementation={false}
numColumns={1}
onRefresh={this._onRefresh}
@ -145,22 +152,31 @@ class FlatListExample extends React.PureComponent {
};
_shouldItemUpdate(prev, next) {
/**
* Note that this does not check state.horizontal or state.fixedheight because we blow away the
* whole list by changing the key in those cases. Make sure that you do the same in your code,
* or incorporate all relevant data into the item data, or skip this optimization entirely.
* Note that this does not check state.horizontal or state.fixedheight
* because we blow away the whole list by changing the key in those cases.
* Make sure that you do the same in your code, or incorporate all relevant
* data into the item data, or skip this optimization entirely.
*/
return prev.item !== next.item;
}
// This is called when items change viewability by scrolling into or out of the viewable area.
// This is called when items change viewability by scrolling into or out of
// the viewable area.
_onViewableItemsChanged = (info: {
changed: Array<{
key: string, isViewable: boolean, item: any, index: ?number, section?: any
key: string,
isViewable: boolean,
item: any,
index: ?number,
section?: any,
}>
}
) => {
// Impressions can be logged here
if (this.state.logViewable) {
infoLog('onViewableItemsChanged: ', info.changed.map((v) => ({...v, item: '...'})));
infoLog(
'onViewableItemsChanged: ',
info.changed.map((v) => ({...v, item: '...'})),
);
}
};
_pressItem = (key: number) => {

View File

@ -81,7 +81,9 @@ class SectionListExample extends React.PureComponent {
};
render() {
const filterRegex = new RegExp(String(this.state.filterText), 'i');
const filter = (item) => (filterRegex.test(item.text) || filterRegex.test(item.title));
const filter = (item) => (
filterRegex.test(item.text) || filterRegex.test(item.title)
);
const filteredData = this.state.data.filter(filter);
return (
<UIExplorerPage
@ -104,8 +106,12 @@ class SectionListExample extends React.PureComponent {
<SectionList
ListHeaderComponent={HeaderComponent}
ListFooterComponent={FooterComponent}
SectionSeparatorComponent={() => <CustomSeparatorComponent text="SECTION SEPARATOR" />}
ItemSeparatorComponent={() => <CustomSeparatorComponent text="ITEM SEPARATOR" />}
SectionSeparatorComponent={() =>
<CustomSeparatorComponent text="SECTION SEPARATOR" />
}
ItemSeparatorComponent={() =>
<CustomSeparatorComponent text="ITEM SEPARATOR" />
}
enableVirtualization={this.state.virtualized}
onRefresh={() => alert('onRefresh: nothing to refresh :P')}
onViewableItemsChanged={this._onViewableItemsChanged}
@ -117,8 +123,8 @@ class SectionListExample extends React.PureComponent {
{title: 'Item In Header Section', text: 'Section s1', key: '0'},
]},
{key: 's2', data: [
{noImage: true, title: 'First item', text: 'Section s2', key: '0'},
{noImage: true, title: 'Second item', text: 'Section s2', key: '1'},
{noImage: true, title: '1st item', text: 'Section s2', key: '0'},
{noImage: true, title: '2nd item', text: 'Section s2', key: '1'},
]},
{key: 'Filtered Items', data: filteredData},
]}
@ -127,11 +133,18 @@ class SectionListExample extends React.PureComponent {
</UIExplorerPage>
);
}
_renderItemComponent = ({item}) => <ItemComponent item={item} onPress={this._pressItem} />;
// This is called when items change viewability by scrolling into our out of the viewable area.
_renderItemComponent = ({item}) => (
<ItemComponent item={item} onPress={this._pressItem} />
);
// This is called when items change viewability by scrolling into our out of
// the viewable area.
_onViewableItemsChanged = (info: {
changed: Array<{
key: string, isViewable: boolean, item: {columns: Array<*>}, index: ?number, section?: any
key: string,
isViewable: boolean,
item: {columns: Array<*>},
index: ?number,
section?: any
}>},
) => {
// Impressions can be logged here

View File

@ -48,19 +48,24 @@ const requireNativeComponent = require('requireNativeComponent');
* view from becoming the responder.
*
*
* `<ScrollView>` vs `<ListView>` - which one to use?
* ScrollView simply renders all its react child components at once. That
* makes it very easy to understand and use.
* On the other hand, this has a performance downside. Imagine you have a very
* long list of items you want to display, worth of couple of your ScrollView's
* heights. Creating JS components and native views upfront for all its items,
* which may not even be shown, will contribute to slow rendering of your
* screen and increased memory usage.
* `<ScrollView>` vs [`<FlatList>`](/react-native/docs/flatlist.html) - which one to use?
*
* This is where ListView comes into play. ListView renders items lazily,
* just when they are about to appear. This laziness comes at cost of a more
* complicated API, which is worth it unless you are rendering a small fixed
* set of items.
* `ScrollView` simply renders all its react child components at once. That
* makes it very easy to understand and use.
*
* On the other hand, this has a performance downside. Imagine you have a very
* long list of items you want to display, maybe several screens worth of
* content. Creating JS components and native views for everythign all at once,
* much of which may not even be shown, will contribute to slow rendering and
* increased memory usage.
*
* This is where `FlatList` comes into play. `FlatList` renders items lazily,
* just when they are about to appear, and removes items that scroll way off
* screen to save memory and processing time.
*
* `FlatList` is also handy if you want to render separators between your items,
* multiple columns, infinite scroll loading, or any number of other features it
* supports out of the box.
*/
const ScrollView = React.createClass({
propTypes: {

View File

@ -49,19 +49,6 @@ import type {ViewabilityConfig, ViewToken} from 'ViewabilityHelper';
type Item = any;
type renderItemType = (info: {item: Item, index: number}) => ?React.Element<any>;
/**
* Renders a virtual list of items given a data blob and accessor functions. Items that are outside
* the render window (except for the initial items at the top) are 'virtualized' e.g. unmounted or
* never rendered in the first place. This improves performance and saves memory for large data
* sets, but will reset state on items that scroll too far out of the render window.
*
* TODO: Note that LayoutAnimation and sticky section headers both have bugs when used with this and
* are therefor not supported, but new Animated impl might work?
* https://github.com/facebook/react-native/pull/11315
*
* TODO: removeClippedSubviews might not be necessary and may cause bugs?
*
*/
type RequiredProps = {
renderItem: renderItemType,
/**
@ -76,7 +63,7 @@ type OptionalProps = {
SeparatorComponent?: ?ReactClass<any>,
/**
* `debug` will turn on extra logging and visual overlays to aid with debugging both usage and
* implementation.
* implementation, but with a significant perf hit.
*/
debug?: ?boolean,
/**
@ -85,13 +72,28 @@ type OptionalProps = {
* this for debugging purposes.
*/
disableVirtualization: boolean,
getItem: (items: any, index: number) => ?Item,
getItemCount: (items: any) => number,
getItemLayout?: (items: any, index: number) =>
/**
* A generic accessor for extracting an item from any sort of data blob.
*/
getItem: (data: any, index: number) => ?Item,
/**
* Determines how many items are in the data blob.
*/
getItemCount: (data: any) => number,
getItemLayout?: (data: any, index: number) =>
{length: number, offset: number, index: number}, // e.g. height, y
horizontal?: ?boolean,
/**
* How many items to render in the initial batch. This should be enough to fill the screen but not
* much more.
*/
initialNumToRender: number,
keyExtractor: (item: Item, index: number) => string,
/**
* The maximum number of items to render in each incremental render batch. The more rendered at
* once, the better the fill rate, but responsiveness my suffer because rendering content may
* interfere with responding to button taps or other interactions.
*/
maxToRenderPerBatch: number,
onEndReached?: ?(info: {distanceFromEnd: number}) => void,
onEndReachedThreshold?: ?number, // units of visible length
@ -110,15 +112,34 @@ type OptionalProps = {
* Set this true while waiting for new data from a refresh.
*/
refreshing?: ?boolean,
/**
* A native optimization that removes clipped subviews (those outside the parent) from the view
* hierarchy to offload work from the native rendering system. They are still kept around so no
* memory is saved and state is preserved.
*/
removeClippedSubviews?: boolean,
/**
* Render a custom scroll component, e.g. with a differently styled `RefreshControl`.
*/
renderScrollComponent: (props: Object) => React.Element<any>,
shouldItemUpdate: (
props: {item: Item, index: number},
nextProps: {item: Item, index: number}
) => boolean,
/**
* Amount of time between low-pri item render batches, e.g. for rendering items quite a ways off
* screen. Similar fill rate/responsiveness tradeoff as `maxToRenderPerBatch`.
*/
updateCellsBatchingPeriod: number,
viewabilityConfig?: ViewabilityConfig,
windowSize: number, // units of visible length
/**
* Determines the maximum number of items rendered outside of the visible area, in units of
* visible lengths. So if your list fills the screen, then `windowSize={21}` (the default) will
* render the visible screen area plus up to 10 screens above and 10 below the viewport. Reducing
* this number will reduce memory consumption and may improve performance, but will increase the
* chance that fast scrolling may reveal momentary blank areas of unrendered content.
*/
windowSize: number,
};
export type Props = RequiredProps & OptionalProps;
@ -148,6 +169,12 @@ type State = {first: number, last: number};
* and we are working on improving it behind the scenes.
* - By default, the list looks for a `key` prop on each item and uses that for the React key.
* Alternatively, you can provide a custom keyExtractor prop.
*
* NOTE: `LayoutAnimation` and sticky section headers both have bugs when used with this and are
* therefore not officially supported yet.
*
* NOTE: `removeClippedSubviews` might not be necessary and may cause bugs. If you see issues with
* content not rendering, try disabling it, and we may change the default there.
*/
class VirtualizedList extends React.PureComponent<OptionalProps, Props, State> {
props: Props;