javascript - 使用 React WayPoint 按需加载表行
问题描述
我正在使用材质 UI 表和反应表的混合体。当表中的行数超过 ~200 行时,性能就不那么好了。所以我试图在开始时显示固定数量的行(假设 20 行),每当我向下滚动时,都会触发一个回调,将行附加到现有行。我正在使用 react-waypoint 启动回调,但无法弄清楚如何将行附加到当前列表的末尾。这是我的表格组件。
export default function TmpTable(props) {
let data = props.rows;
let columns = props.columns;
const {getTableProps,getTableBodyProps,headerGroups,rows,prepareRow,} = useTable({columns,data,});
let slicedRows= [];
//considering only few rows
slicedRows = rows.slice(0, 10);
return (
<TableContainer style={{ maxHeight: "350px" }}>
<Table size="small" stickyHeader>
<TableHead>
{headerGroups.map((headerGroup) => (
<TableRow {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column) => (
<TableCell
key={column.id}
id={"columns" + column.Header}
>
<span>{column.render("Header")}</span>
</TableCell>
))}
</TableRow>
))}
</TableHead>
<TableBody {...getTableBodyProps()}>
{slicedRows.map((row, i) => {
prepareRow(row);
return (
<>
<TableRow {...row.getRowProps()} style={{ height: "35px" }}>
{row.cells.map((cell) => {
return (
<TableCell {...cell.getCellProps()}>
{cell.render("Cell")}
</TableCell>
);
})}
</TableRow>
<Waypoint onEnter={() => console.log('need to add a callback that adds more rows')}/>
</>
);
})}
</TableBody>
</Table>
</TableContainer>
);
}
我知道 react-window 可以虚拟化行,但我已经创建了一个复杂的表,其中包含扩展行、行选择复选框等,并且向其中添加虚拟化似乎是不可能的。所以我认为我唯一的选择是在我上面提供的示例表代码中按需附加更多行。我不能使用钩子来存储它,slicedRows
因为它会重新渲染整个组件并且我必须从头开始滚动。那么有没有办法使用 Waypoint 按需追加行?如果没有,任何人都可以建议任何其他替代方案来按需向 DOM 添加行吗?
解决方案
不完全是手头问题的答案,但重新渲染可能是不可避免的。您可以尝试通过记忆单元来减轻性能损失(以下示例使用lodash
and React.memo
):
const compareAccessors = (accessors, prevRow, nextRow) => (
accessors.map((index) => (
isEqual(get(prevRow, index, null), get(nextRow, index, null))
)).reduce((last, next) => last && next, true)
);
const Cell = memo((cellData) => {
const {
cell,
index,
} = cellData;
const tableCell = <Table.Cell key={index} {...cell.getCellProps()}>{cell.render('Cell')}</Table.Cell>;
return tableCell;
}, (prevprops, nextprops) => {
if (!nextprops.cell.column.accessors) {
// simple comparison of single cell accessor
return prevprops.cell.value == nextprops.cell.value;
}
// more complex comparison of accessors array on the cell.
return compareAccessors(
nextprops.cell.column.accessors,
prevprops.cell.row.original,
nextprops.cell.row.original,
);
});
使用如下:
const columns =[
{
Header: 'Id',
accessor: 'id',
},
{
Header: 'Two Values',
accessor: 'id',
accessors: ['id', 'name'],
Cell: ({row: { original: { id, name }}}) => (
<div>${id}-${name}</div>
)
},
]
你可以更进一步,也可以记住你的行,但我在这里不包括示例代码。
推荐阅读
- python - 随机模块中的参考问题
- python - 如何使 APScheduler ProcessPoolExecutor 在完成后关闭进程并仅生成它需要的进程?
- java - 休眠生成的错误查询
- c - C 中有什么东西可以阻止我的大量数字变成“6.95278e-310”。我想打印完整的号码
- python-3.x - 无法在 python 中使用 gphoto2 打开相机
- javascript - 如何从我的 HTML 表单中获取字符串到 DOM 上?
- numpy - 使用 matplotlib 将 1D numpy 数组可视化为 2D 数组
- java - 如何修复“线程中的异常”main“java.util.NoSuchElementException:找不到行”和其他两个错误?
- python-3.x - Python 3.7 猜数字程序在选项一完成时不会循环回选项输入
- javascript - 尝试解决循环和推送到数组引起的“ParallelSaveError”。使用 Mongoose 和 Mongo