<List>
allows you to efficiently render a large list of items.
The <List>
can render the items in two ways: as an array of <ListItem>
elements or as a render callback (Function as Children). It is recommended to use the render callback since it will virtualize all the items, making it very fast when a large numer of items is provided.
If the width and height are not specified through the style
or className
props, it will fill the height and the width of the container, unless width="fit-content"
is provided as a prop. Then it will size the <List>
container to be as wide as the widest measured <ListItem>
component.
Usage
import { List } from 'nr1'
Examples
Basic
function render() { return ( <List rowHeight={20}> <ListItem>Item 1</ListItem> <ListItem>Item 2</ListItem> <ListItem>Item 3</ListItem> <ListItem>Item 4</ListItem> </List> );}
Render callback
function render() { const items = new Array(10000).fill().map((_, i) => { return { key: `foo-${i}`, name: `Item ${i}` }; });
const style = { width: 200, height: 300 };
return ( <List style={style} rowHeight={20} items={items}> {({ item }) => <ListItem key={item.key}>{item.name}</ListItem>} </List> );}
Lazy loading
function render() { // This example assumes you have a way to know/load this information. const remoteTotalNumberOfItems = 9000;
const items = [ { id: 1, text: 'Item 1' }, { id: 2, text: 'Item 2' }, { id: 3, text: 'Item 3' }, { id: 4, text: 'Item 4' }, ];
function loadMoreItems({ startIndex, stopIndex }) { return fetch(`path/to/api?start=${startIndex}&stop=${stopIndex}`).then( () => { // Store items in list... }, ); }
const style = { width: 200, height: 300 };
return ( <div style={style}> <List items={items} rowCount={remoteTotalNumberOfItems} onLoadMore={loadMoreItems} > {({ item }) => <ListItem key={item.id}>{item.text}</ListItem>} </List> </div> );}
Auto-sizing to content width
class AutoSizingList extends React.Component { constructor() { super(...arguments); this.state = { items: this._generateItems(0), }; this._maxItems = 1000; this._onLoadMore = this._onLoadMore.bind(this); }
_onLoadMore(cursor) { return ( Promise.resolve() // Fetch more items to load into <List> .then(() => this._generateItems(this.state.items.length)) .then((moreItems) => // Add retrieved items to the stored list this.setState(({ items }) => ({ items: items.concat(moreItems) })), ) ); }
_generateString(num, extra = 0) { return `Entity ${num.toString(10)}: 1${'00'.repeat( Math.floor(Math.random() * 10) + 1 + extra, )} bytes`; }
_generateItems(start) { return new Array(200).fill().map((_, i) => ({ key: `foo-${start + i}`, name: this._generateString(start + i, start / 100), })); }
render() { const style = { 'height': 300, 'background-color': 'white' }; const parentStyle = { width: 260 };
return ( <div style={parentStyle}> <List rowCount={this._maxItems} onLoadMore={this._onLoadMore} style={{ ...style }} rowHeight={20} items={this.state.items} width="fit-content" > {({ item }) => <ListItem key={item.key}>{item.name}</ListItem>} </List> </div> ); }}
Integration with query components
function render() { const style = { width: 200, height: 300 };
const list = ( <div style={style}> <EntitiesByDomainTypeQuery entityDomain="APM" entityType="APPLICATION"> {({ fetchMore, loading, data }) => { const { results, count } = data.actor.entitySearch;
return ( <List rowHeight={40} items={results.entities} onLoadMore={fetchMore} rowCount={count} > {({ item }) => <ListItem key={item.id}>{item.text}</ListItem>} </List> ); }} </EntitiesByDomainTypeQuery> </div> );}
Props
REQUIREDnode|function | It can be either an array of |
string | Classname for custom styling. |
boolean | Expands the stack to occupy all available height. |
boolean | Expands the stack to occupy all available width. |
any[] | The items to be used when rendering.They are required when rendering items with a render callback.Each item can have any structure and type possible, and will the corresponding one will be provided when rendering each element list.
|
function | Callback fired when more items must be loaded. This happens when you're lazy loading the items and the items that are about to render cannot be found in the function ( |
number | Number of rows.By default it's equal to length of array passed in the items prop.You should specify the |
REQUIREDnumber | Height of the list row.Required when rendering items with the render callback (Function as Children). This is a provisional height until the cell content is measured by temporarily rendering it in a way that is not visible to the user. |
enum[] | Spacing property. Spacing is defined as a tuple of zero to four values, which follow the same conventions as CSS properties like <Array of |
object | Inline style for custom styling. |
string | Adds a Note: You might not see |
string | Represents the width of the list. It is always a string, and it can be of one of the following types:
|
Type definitions
RenderCallbackArguments
{item: any, Item to render.
index: number, Index of the item in the items array.
items: any[], Array of items which we're iterating on.
}
Cursor
{startIndex: number, First index of the range of items to load.
stopIndex: number, Last index of the range of items to load.
}