<!DOCTYPE html>
<html>
<head>
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script crossorigin src="https://unpkg.com/react-virtualized/dist/umd/react-virtualized.js"></script>
<link rel="stylesheet" href="https://unpkg.com/react-virtualized/styles.css">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div id="example">
<!-- This element's contents will be replaced with your code... -->
</div>
<script src="script.js"></script>
</body>
</html>
var List = ReactVirtualized.List;
var InfiniteLoader = ReactVirtualized.InfiniteLoader;
var AutoSizer = ReactVirtualized.AutoSizer;
var WindowScroller = ReactVirtualized.WindowScroller;
var CellMeasurer = ReactVirtualized.CellMeasurer;
var CellMeasurerCache = ReactVirtualized.CellMeasurerCache;
var pageKey = 0;
var apiList = Array.from(
{ length: 100 },
(_, i) => ({
displayName: `li-${i}`,
imageSource: i === 12
? 'https://images.anandtech.com/doci/9853/RTG_Software%20Session_FINAL-page-023.jpg'
: 'https://pbs.twimg.com/profile_images/699768459522154496/y3ILwo06_400x400.png'
})
);
var list = [];
var _isRowLoaded = ({ index }) => !!list[index];
var _loadMoreRows = () => {
list = list.concat(apiList.slice(pageKey, mockNextPageKeyFromAPI()))
console.log(list.length)
return Promise.resolve();
}
var cache = new CellMeasurerCache({
defaultHeight: 30,
fixedWidth: true
});
var _rowRenderer = ({ index, isScrolling, key, parent, style }) => (
<CellMeasurer
cache={cache}
columnIndex={0}
rowIndex={index}
{...{ key, parent }}
>
{({ measure }) =>
<div
className='Row'
style={style}
key={key}
>
{
!list[index]
? 'loading'
: (
<ListItem
displayName={list[index].displayName}
imageSource={list[index].imageSource}
measure={measure}
/>
)
}
</div>
}
</CellMeasurer>
);
var app = (
<div style={{ display: 'flex', height: '100vh', width: '60%' }}>
<div style={{ flex: '1 1 auto' }}>
<InfiniteLoader
isRowLoaded={_isRowLoaded}
loadMoreRows={_loadMoreRows}
rowCount={apiList.length}
>
{({ onRowsRendered, registerChild }) =>
<WindowScroller>
{({ height, isScrolling, scrollTop }) =>
<AutoSizer disableHeight>
{({ width }) =>
<List
className='List'
ref={registerChild}
width={width}
height={height}
autoHeight
rowCount={apiList.length}
deferredMeasurementCache={cache}
rowHeight={cache.rowHeight}
onRowsRendered={onRowsRendered}
rowRenderer={_rowRenderer}
scrollTop={scrollTop}
/>
}
</AutoSizer>
}
</WindowScroller>
}
</InfiniteLoader>
</div>
</div>
);
ReactDOM.render(app, document.getElementById('example'));
function mockNextPageKeyFromAPI() {
pageKey = pageKey + 30;
return pageKey;
}
function ListItem({ displayName, imageSource, measure }) {
return (
<div>
{displayName}
<img
onLoad={measure}
src={imageSource}
/>
</div>
)
}
.List {
border: 1px solid black;
box-sizing: border-box;
}
.Row {
width: 100%;
height: 100%;
border-bottom: 1px solid black;
display: flex;
align-items: center;
padding: 0 0.5rem;
box-sizing: border-box;
}