yarn add react-virtualized
VirtualizedScroll组件
/*
* @Description:
* @Date: 2022-02-27 22:29:33
* @LastEditTime: 2022-02-28 01:17:41
* @FilePath: \test3\src\pages\VirtualizedScroll\index.jsx
*/
import { InfiniteLoader, List } from 'react-virtualized'
import { Spin } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
const VirtualizedScroll = ({
//是否还有下一页 boolean
hasNextPage,
// 渲染数组 Array
list,
// 加载更多的函数
loadMoreRows,
// 滚动窗口的高度 number
height,
// 滚动窗口的高度 width
width,
// 渲染数组每一项的高度
rowHeight,
}) => {
// 加载更多的图标
const antIcon = <LoadingOutlined style={{ fontSize: 12 }} spin />
// +1 是为了显示没有更多了
const rowCount = list.length + 1
// Every row is loaded except for our loading indicator row.
const isRowLoaded = ({ index }) => !hasNextPage || index < list.length
// Render a list item or a loading indicator.
const rowRenderer = ({ index, key, style }) => {
let content
if (!isRowLoaded({ index })) {
content = <Spin indicator={antIcon} tip="加载中..." />
} else {
content = list[index]
}
if (!hasNextPage && index === list.length) {
return (
<div key={key} style={style}>
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
height: '100%',
}}
>
<span>没有更多了...</span>
</div>
</div>
)
}
return (
<div key={key} style={style}>
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
height: '100%',
border: '1px solid #ccc',
backgroundColor: 'skyblue',
}}
>
<span>{content}</span>
</div>
</div>
)
}
return (
<InfiniteLoader
isRowLoaded={isRowLoaded}
loadMoreRows={loadMoreRows}
rowCount={rowCount}
>
{({ onRowsRendered, registerChild }) => {
return (
<List
height={height || document.documentElement.clientHeight}
width={width || document.documentElement.clientWidth}
ref={registerChild}
onRowsRendered={onRowsRendered}
rowRenderer={rowRenderer}
rowCount={rowCount}
rowHeight={
rowHeight || Math.ceil(document.documentElement.clientHeight / 15)
}
/>
)
}}
</InfiniteLoader>
)
}
export default VirtualizedScroll
使用
const [list, setList] = useState([])
const [hasNextPage, setHasNextPage] = useState(true)
const loadMoreRows = ({ startIndex, stopIndex }) => {
if (list.length > 100) {
setHasNextPage(false)
} else {
setTimeout(() => {
setList((pre) => [
...pre,
1
])
}, 1500)
}
}
<VirtualizedScroll
hasNextPage={hasNextPage}
list={list}
loadMoreRows={loadMoreRows}
/>