A browser efficient infinite list for React apps that allows loading of items with differing heights and sizes.
The minimal API is to create a ListViewDataSource
from clarity-react-infinite-list
, populate it with an array of data, and add a ListView
component
with that data source and a renderRow
callback which takes an item from the data source and returns a renderable component.
npm install clarity-react-infinite-list
- Lazy load and fetch data from API requests in batches.
- Infinite number of items and batches
- Items can have dynamic heights and sizes, that do not have to be declared before hand.
- Add in a custom loading component.
react
react-dom
import React, { Component } from "react";
import { connect } from "react-redux";
import { getUsersBatch, setFetchingUsersStatus } from "../../actions";
import { ListView, ListViewDataSource } from "clarity-react-infinite-list";
import ListItem from "../layouts/ListItem";
const styles = {...};
class Main extends Component {
constructor(props) {
super(props);
this.state = {
dataSource: new ListViewDataSource(30),
lastUserId: 0
};
this._renderRow = this._renderRow.bind(this);
this._onEndReached = this._onEndReached.bind(this);
this._loadingComponent = this._loadingComponent.bind(this);
}
_renderRow(rowData, rowId) {
return (
<ListItem key={rowId} rowData={rowData} rowId={rowId} />
);
}
_onEndReached() {
if (!this.props.isFetchingUsers) {
this.props.setFetchingUsersStatus(true);
this.props.getUsersBatch(this.state.lastUserId);
}
}
_loadingComponent() {
return (
<div style={styles.loading}>Loading...</div>
);
}
componentWillMount() {
this.props.setFetchingUsersStatus(true);
this.props.getUsersBatch(this.state.lastUserId);
}
componentWillReceiveProps(nextProps) {
if (nextProps.users[nextProps.users.length - 1] && this.state.lastUserId !== nextProps.users[nextProps.users.length - 1].id) {
this.setState({
dataSource: this.state.dataSource.cloneWithRows(nextProps.users),
lastUserId: nextProps.users[nextProps.users.length - 1].id,
});
}
}
render() {
return (
<div style={styles.container}>
<div style={styles.header}>
Clarity React Infinite Scroll Example
</div>
<ListView style={styles.listView}
dataSource={this.state.dataSource}
renderRow={this._renderRow}
onEndReached={this._onEndReached}
loadingComponent={this._loadingComponent}
onEndReachedThreshold={5000}
ref={listView => this.listView = listView} />
</div>
);
}
}
const mapStateToProps = (state) => {
return {
users: state.users,
isFetchingUsers: state.isFetchingUsers
};
};
const mapDispatchToProps = {
getUsersBatch,
setFetchingUsersStatus
};
export default connect(mapStateToProps, mapDispatchToProps)(Main);
- An instance of
ListViewDataSource
to use.
- Takes a data entry from the data source and its id and should return a renderable component to be rendered as the row.
- Called when the list has been scrolled to within the
onEndReachedThreshold
of the bottom.
- Should return a renderable component, to be displayed at bottom of list when loading new batches.
- Threshold in pixels for calling
onEndReached
- Scrolls to the given topPosition of the
ListView
.
- Returns a boolean of whether or not the
ListView
has enough content to have an active vertical scrollbar.
- Manually dig batches from the props.onEndReached function.