react-variable-height-infinite-scroller
An infinite scroller especially made for variable row heights (no precomputation of row height necessary).
See a Demo
Why
Because sometimes you don't know the size of the rows you're going to render before rendering
Install:
npm i --save react-variable-height-infinite-scroller
Usage:
Props
averageElementHeight number | required | This is a guess you make of what is the average height. This is used to approximate number of rows when rendering more or less rows |
containerHeight number | required | Maximum height of the scroll container |
preloadRowStart number | required | If you want to start at a particular row to begin with |
totalNumberOfRows number | required | Length of the data array |
renderRow function | required | Function to render a row |
rowToJumpTo | (optional) | Object of shape { row: Number } . Row you want to jump to. Must be passed as a new object each time to allow for difference checking |
containerClassName string | (optional) infiniteContainer | className to apply on container |
onScroll function | (optional) no-op | Hook to call on scroll |
Taken from the demo code:
import React from 'react';
import InfiniteScroller from './InfiniteScroller.js';
function getFakeRowsWithHeights(numberOfRows) {
let newFakeRows = [];
for (let i = 0; i < numberOfRows; i++) {
newFakeRows.push({height: Math.floor(1000 * Math.random())});
}
return newFakeRows;
}
const App = React.createClass({
getNewRandomRow(totalRows) {
return {row: Math.floor(totalRows * Math.random())};
},
getInitialState() {
return {
rowToJumpTo: null,
newRowToJumpTo: this.getNewRandomRow(100),
fakeRows: getFakeRowsWithHeights(100),
};
},
render() {
const newNumberOfRowsToDisplay = Math.floor(Math.random() * 200);
return (
<div overflow="scroll">
<button onClick={() => {
this.setState({
rowToJumpTo: this.state.newRowToJumpTo,
newRowToJumpTo: this.getNewRandomRow(this.state.fakeRows.length),
});
}}>
Jump to a random row: Row #{this.state.newRowToJumpTo.row} (its height is {this.state.fakeRows[this.state.newRowToJumpTo.row].height})
</button>
<button onClick={() => {
this.setState({
fakeRows: getFakeRowsWithHeights(newNumberOfRowsToDisplay),
});
}}>
Create {newNumberOfRowsToDisplay} new rows
</button>
<InfiniteScroller
averageElementHeight={100} // this is a guess you make!
containerHeight={600}
rowToJumpTo={this.state.rowToJumpTo} // (optional) row you want to jump to. Must be passed as a new object each time to allow for difference checking
renderRow={renderRow} // function to render a row
totalNumberOfRows={this.state.fakeRows.length} // an array of data for your rows
preloadRowStart={10} // if you want to start at a particular row to begin with
/>
</div>
);
},
renderRow(rowNumber) {
const heightOfRow = this.state.fakeRows[rowNumber].height;
return (
<div
key={rowNumber}
style={{height: heightOfRow, background: heightOfRow % 2 === 0 ? 'red' : 'orange'}}
>
{heightOfRow}
</div>
);
},
});
React.render(<App />, document.getElementById('container'));
Contributing
Changelog is now autogenerated. So commits have to be prefixed by one the four following prefixes:
[added]
added a new feature
[changed]
changed an existing feature
[fixed]
fixed a bug
[removed]
removed something or a file
Run npm test
to lint
#Changelog:
Changelog