react-window虚拟渲染(不固定高度)
前言
最近有个需求,需要渲染大量的列表,列表项的高度还不确定,之前用过react-virtualized,可以解决不固定高度的问题,但这个库有点大,比较重。react-window官方没有提供该案例。
react-window实现
react-window提供了两种组件VariableSizeList
可变size,FixedSizeList
固定size两种类型的组件。我们借助VariableSizeList
来实现不固定高度。我们先看看VariableSizeList
的简单使用方法。需重点关注一下resetAfterIndex(index, false);
改方法,因为react-window内容部为了性能做了缓存,我们调用改方法可以清楚缓存,重新计算结果。
VariableSizeList 详解
List 组件
主要使用VariableSizeList
组件, props上有一个itemSize
属性,改属性接收一个方法,参数为index
, 具体内容可见getItemSize
。组件内部提供了一个setItemSize
方法,供Item组件设置高度。
const Example = () => {
const [sizes, setSizes] = useState({ 1: 50 }); // 根据索引记录列表的高度
const [count, setCount] = useState(100); // 列表数量
const listRef = useRef();
console.log("sizes", sizes);
useEffect(() => {
return () => {
console.log("父组件");
};
}, []);
// 根据索引获取Item的尺寸
const getItemSize = useCallback(
(index) => {
return sizes[index] || 150;
},
[sizes]
);
// 根据索引,设置Item高度
const setItemSize = useCallback((index = 1, size = 10) => {
console.log("setItemSize", index, size);
setSizes((prevSize) => {
return {
...prevSize,
[index]: size
};
});
// setCount(count + 1);
// 根据索引,重置缓存位置。
listRef.current.resetAfterIndex(index, false);
}, []);
const rowRender = useCallback(({ index: rowIndex, style }) => {
return (
<div index={rowIndex} style={style}>
<Row
// style={style}
index={rowIndex}
key={rowIndex}
setItemSize={setItemSize}
rowIndex={rowIndex}
/>
</div>
);
}, []);
return (
<>
{
<List
className="List"
height={400}
itemCount={count}
itemSize={getItemSize}
width={300}
ref={listRef}
>
{rowRender}
</List>
}
</>
);
};
RowItem组件
RowItem组件在页面第一次渲染完成后,获取组件的高度,调用一下父组件setItemSize
方法,更新下高度。
/**
* 项(Item)组件
*/
const Row = ({ index, style, setItemSize }) => {
const itemRef = useRef();
useEffect(() => {
const elementHeight = itemRef.current.offsetHeight;
console.log("elementHeight", elementHeight);
setItemSize(index, elementHeight);
return () => {
console.log("卸载1");
};
}, []);
return (
<div
ref={itemRef}
className={index % 2 ? "ListItemOdd" : "ListItemEven"}
style={style}
>
Row {index}
</div>
);
};
完整的代码可以查看 codesandbox.io/s/modern-vi…
结束语
大家有不固定高度的虚拟渲染需求,可以用React-window尝试一下。
如果你觉得该文章不错,不妨
1、点赞,让更多的人也能看到这篇内容
2、关注我,让我们成为长期关系
3、关注公众号「前端有话说」,里面已有多篇原创文章,和开发工具,欢迎各位的关注,第一时间阅读我的文章
转载自:https://juejin.cn/post/7120463085856358414