如何在 Material UI 的自动完成组件中使用虚拟列表?
显示数据列表是 Web 应用程序的常见需求。或者带有可滚动标题的表格。您很可能已经无数次地执行过它。但是,如果您必须同时显示数千行数据会怎样?
在本文中,我们将了解如何使用 Material UI 的自动完成组件的虚拟列表来生成具有大型数据集的流畅用户界面。流行的 React UI 框架 Material UI 提供了大量具有尖端设计和一流性能的组件。在处理自动完成组件中的大型数据集时,传统的渲染技术可能会导致性能问题,因此为了防止这些问题,我们将使用 react-virtualized 来有效地显示大量数据。
了解虚拟列表
虚拟列表,也称为无限滚动,是一种更有效地渲染长列表的方法,方法是仅显示屏幕上可见的项目。虚拟列表根据用户的视口渲染较小的项目子集,而不是渲染整个数据集,从而导致加载时间更快,滚动更流畅。
为什么要使用 react-virtualized?
经常使用 React 的开发人员会渲染包含多行的列表并使用 map 函数。即使滚动条通常会隐藏溢出的内容,但如果他们使用该方法渲染数千行,Web 浏览器仍会始终生成数千个 DOM 元素。当用户事件(如滚动)导致 DOM 元素位置发生变化时,渲染新的 DOM 元素需要物理内存并使用 CPU 和 GPU 硬件。
一种性能友好的渲染大型列表的方法是使用像 react-virtualized 这样的库,它使用虚拟渲染来一次渲染大量元素的列表。为了最大程度地减少对应用程序的性能影响,此库通常仅渲染长列表中可见的行并生成更少的 DOM 元素。换句话说,此库仅显示必要的行,同时使用 CSS 样式虚拟指示隐藏行的存在。
在自动完成中使用虚拟列表的步骤
步骤 1:创建 React 应用程序
第一步是创建一个新的 react 应用程序(如果尚未创建)。我们将使用传统方法,即 create-react-app。
npx create-react-app myproject cd myproject
步骤 2:安装和导入 Material UI
创建 react 应用程序后,让我们首先安装 material ui 及其依赖项,然后导入它。
npm install @mui/material @emotion/react @emotion/styled // Importing the autocomplete virtualized import React from 'react'; import AutocompleteVirtualized from '@mui/lab/AutocompleteVirtualized'; import TextField from '@mui/material/TextField';
步骤 3:创建虚拟数据集
要使用虚拟列表,我们必须首先创建一个数据集。因此,现在我们将使用数组来创建虚拟数据集。稍后我们还将了解如何使用动态 API 数据列表。
const dataset = Array.from({ length: 500 }, (_, index) => ({
title: `Option ${index + 1}`,
val: index + 1,
}));
在这里,我们创建了一个包含 500 个虚拟数据集的列表,其中 title 和 val 是数据集的选项。
步骤 4:在自动完成中定义虚拟列表
现在,我们已经创建了自己的虚拟数据集,让我们将其集成到虚拟化的自动完成中。以下是使用它们的语法:
const CustomVirtualComponent = () => {
return (
<AutocompleteVirtualized
options={dataset}
getOptionLabel={(item) => item.title}
renderInput={(params) => <TextField {...params} label="Add label" />}
/>
);
};
示例
在此示例中,我们使用数组函数创建了一个虚拟数据集,该函数生成大约 400 个项目的随机列表,其标签和 val 作为其选项。然后,使用我们使用 react-window 的 VariableSizeList 创建的自定义 ListboxComponent 有效地渲染这些项目,并且仅在必要时渲染列表以获得最佳性能,即使选项数量很大也是如此。
import React, { useState } from "react";
import Autocomplete from "@mui/material/Autocomplete";
import TextField from "@mui/material/TextField";
import { VariableSizeList } from "react-window";
const virtualDataSet = () => {
const arrayOfData = [];
for (let j = 0; j < 400; j++) {
arrayOfData.push({
title: `Random ${j}`,
val: j,
});
}
return arrayOfData;
};
const dataset = virtualDataSet();
const ItemListComponent = React.forwardRef(function ListboxComponent(
{ children, ...other },
ref
) {
const getItemSize = (index) => {
return 35;
};
const itCount = Array.isArray(children) ? children.length : 0;
return (
<div ref={ref}>
<VariableSizeList
height={itCount * 35}
itemSize={getItemSize}
itemCount={itCount}
overscanCount={10}
{...other}>
{({ index, style }) => <div style={style}>{children[index]}</div>}
</VariableSizeList>
</div>
);
});
export default function App() {
const [ipVal, setIpVal] = useState("");
const handleVal = (event, value) => {
setIpVal(value);
};
return (
<div
style={{
display: "flex",
marginTop: 30,
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
}}>
<h3>Select a option</h3>
<Autocomplete
options={dataset}
inputValue={ipVal}
sx={{ width: "70%" }}
getOptionLabel={(item) => item.title}
ListboxComponent={ItemListComponent}
onInputChange={handleVal}
renderInput={(params) => (
<TextField
{...params}
label="select option from virtual list"
variant="standard"
/>
)}
/>
</div>
);
}
输出
示例
在此示例中,我们利用数组函数创建了一个数据集,该数据集生成大约 400 个项目的列表。这些项目以标签和 val 作为其选项。为了增强吸引力,我们在自动完成组件中合并了背景颜色和样式。这些项目的渲染由我们使用 react 窗口 VariableSizeList 开发的自定义 ListboxComponent 高效处理。即使处理大量选项,这也确保了性能,因为渲染了必要的项目。
import React, { useState } from "react";
import Autocomplete from "@mui/material/Autocomplete";
import TextField from "@mui/material/TextField";
import { VariableSizeList } from "react-window";
import { Chip } from "@mui/material";
const virtualDataSet = () => {
const arrayOfData = [];
for (let j = 0; j < 400; j++) {
arrayOfData.push({
title: `Random ${j}`,
val: j,
});
}
return arrayOfData;
};
const dataset = virtualDataSet();
const ItemListComponent = React.forwardRef(function ListboxComponent(
{ children, ...other },
ref
) {
const getItemSize = (index) => {
return 35;
};
const itCount = Array.isArray(children) ? children.length : 0;
return (
<div ref={ref}>
<VariableSizeList
height={itCount * 35}
itemSize={getItemSize}
itemCount={itCount}
overscanCount={10}
{...other}
>
{({ index, style }) => <div style={style}>{children[index]}</div>}
</VariableSizeList>
</div>
);
}
);
export default function App() {
const [ipVal, setIpVal] = useState("");
const handleVal = (event, value) => {
setIpVal(value);
};
return (
<div
style={{
display: "flex",
marginTop: 30,
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
}}>
<h3>Select a option</h3>
<Autocomplete
options={dataset}
inputValue={ipVal}
sx={{ width: "70%", backgroundColor: "lightgreen", padding: 3, borderRadius: 5 }}
getOptionLabel={(item) => item.title}
ListboxComponent={ItemListComponent}
onInputChange={handleVal}
renderInput={(params) => (
<TextField
sx={{backgroundColor: 'green'}}
{...params}
label="select option from virtual list"
variant="standard"
/>
)}
/>
</div>
);
}
输出
结论
在本文中,我们探讨了如何使用 React 在 Material UI 组件中实现列表。我们集成了 react 窗口等库以启用虚拟化。这种方法使我们能够有效地处理数据集,同时保持快速的加载时间并提供用户体验。通过虚拟化优化渲染和性能,自动完成组件在处理大量数据时提供了可用性。
数据结构
网络
关系数据库管理系统
操作系统
Java
iOS
HTML
CSS
Android
Python
C 编程
C++
C#
MongoDB
MySQL
Javascript
PHP