高级套娃react-virtualized
目录
- 高级套娃react-virtualized
- 概述
- 基本使用
- list
- AutoSizer
- WindowScroller
- InfiniteLoader
- 结尾
概述
- 可以解决页面中长列表的渲染,实现在动态在可视区域加载内容
- react-virtualized 是React组件,用来高效渲染大型列表和表格数据
- GitHub地址: react-virtualized
基本使用
npm install react-virtualized --save
// 安装该组件
- 之后在项目中导入便可
- import { } from ‘react-virtualized’
list
-
GitHub地址:list
-
基本使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27<List
autoHeight
<!-- 组件的宽度 -->
width={width}
<!-- 组件的高度 -->
height={height}
<!-- 每一行的数量 -->
rowCount={count}
<!-- 每行的高度 -->
rowHeight={120}
<!-- 渲染每一行的内容 -->
rowRenderer={this.rowRenderer}
/>
<!-- 渲染每一行的内容 -->
rowRenderer({
key, // 每一行的唯一标识
index, // 索引号
style // 重点属性:一定要给每一个行数添加该样式
isScrolling, // 当前列表是否在滚动中
isVisible, //这一行是否在列表中可见
}) {
return (
<div key={key} style={style}>
{list[index]}
</div>
);
} -
这样使用后虽然可以实现长列表的展示,但是因为高度无法确定所以我们需要另外的高阶组件来进行包装(
AutoSizer ),并且list 组件的滚动条和屏幕的滚动条并不是同一个,所以我们还需要用(WindowScroller )高阶组件来包装list 组件
AutoSizer
- GitHub地址:AutoSizer
- 基本使用
1
2
3
4
5
6
7
8
9<AutoSizer>
<!-- 这个宽度将会自适应屏幕宽度 -->
{({width}) => (
<List
<!-- 省略其他代码 -->
width={width}
/>
)}
</AutoSizer> - 这样使用后
list 组件将会自适应屏幕宽度,虽然这个组件也能提供自适应高度,但是list 组件如果需要滚动,也不能使用AutoSizer 组件提供的高度,虽然可以自适应屏幕高度,但这样list 组件的高度将被固定
WindowScroller
- GitHub地址:WindowScroller
- 基本使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20<WindowScroller>
<!-- 高度、是否正在滚动、滚动条 -->
{({ height, isScrolling, scrollTop }) => (
<AutoSizer>
{({width}) => (
<List
autoHeight
height={height}
isScrolling={isScrolling}
rowCount={...}
rowHeight={...}
rowRenderer={...}
scrollTop={scrollTop}
width={...}
/>
/>
)}
</AutoSizer>
)}
</WindowScroller> - 这样使用后虽然可以基本实现
list 组件的滚动、宽度高度都自适应屏幕,但是这样并不是动态的在可视区域渲染数据,我们需用利用最后一个高阶组件(InfiniteLoader )来进行最后的包装
InfiniteLoader
-
GitHub地址:InfiniteLoader
-
基本使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50<InfiniteLoader
<!-- 数据是否在滚动 -->
isRowLoaded={isRowLoaded}
<!-- 加载更多的数据,当数据快要被滚动完毕时执行 -->
loadMoreRows={loadMoreRows}
<!-- 数据总条数 -->
rowCount={remoteRowCount}
>
<!-- onRowsRendered表示是否滚动完毕 -->
<!-- registerChild 用来注册List组件 -->
{({ onRowsRendered, registerChild }) => (
<WindowScroller>
<!-- 高度、是否正在滚动、滚动条 -->
{({ height, isScrolling, scrollTop }) => (
<AutoSizer>
{({width}) => (
<List
ref={registerChild}
autoHeight
height={height}
isScrolling={isScrolling}
rowCount={...}
rowHeight={...}
rowRenderer={...}
scrollTop={scrollTop}
width={width}
onRowsRendered={onRowsRendered}
/>
/>
)}
</AutoSizer>
)}
</WindowScroller>
)}
</InfiniteLoader>
<!-- 判断数据是否快要滚动完毕 -->
function isRowLoaded ({ index }) {
<!-- 返回一个布尔值 -->
return !!list[index];
}
<!-- 加载更多的数据,每次默认加载十条数据 -->
<!-- startIndex 开始的索引 -->
<!-- stopIndex 结束的索引 -->
function loadMoreRows ({ startIndex, stopIndex }) {
<!-- 需要返回一个Promise数据 -->
return fetch(`path/to/api?startIndex=${startIndex}&stopIndex=${stopIndex}`)
.then(response => {
<!-- 将响应的数据存储在`state`中 -->
})
} -
这样基本上可以实现
list 组件的无限滚动,但是在滚动速度过快时,可能会引起数据加载不过来,导致报错,我们可以在list 组件中的rowRenderer 渲染每一行的方法中添加一个判断,如果当前数组中的那一项并没有值,可能是因为滚动速度过快引起,所以在当数据没有值时,我们可以先渲染一个占位属性,当数据加载完毕在重新显示
-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20<!-- 渲染每一行的内容 -->
rowRenderer({
key, // 每一行的唯一标识
index, // 索引号
style // 重点属性:一定要给每一个行数添加该样式
isScrolling, // 当前列表是否在滚动中
isVisible, //这一行是否在列表中可见
}) {
if(flag) {
return <div>
数据正在加载中
<!-- 也可以使用组件渲染一个骨架屏 -->
</div>
}
return (
<div key={key} style={style}>
{list[index]}
</div>
);
}
-
结尾
- 虽然这个组件需要不停的
套娃 ,但同时也是一款非常优秀的组件,同时还有许多其他的功能,比如宫格组件Grid 、Tabel ,都可以来实现可视区域的动态加载,优化性能。 - tips
- 在使用高阶组件进行包装的时候可能会出现报错,可能是因为,没有把包装的组件
return ,我们可以自己加上一个return
- 在使用高阶组件进行包装的时候可能会出现报错,可能是因为,没有把包装的组件
