Material-UI:设置 rowCount 时 DataGrid 服务器端分页问题

JP *_*lvo 7 reactjs material-ui

所以我刚刚开始使用Material UI,并且非常喜欢它。现在,我们正在开发一个项目,涉及菲律宾某个特定城市的用户、员工和地址的数据,我决定使用表格将其显示给客户,因为我发现这更容易。因此,这个表需要进行分页、排序、过滤等操作,而我们是在服务器端进行这些操作。显然,客户需要发送一些数据,就像{ page: 1, page_size: 50, ....}我们在我的反应中所做的那样。

我现在遇到的问题是我认为它与DataGrid. 我认为在获取数据库中的数据rowCount后该表不会重新呈现。我这里totalRows有沙箱(PS:您必须放大输出屏幕才能看到 。)但是正如您所注意到的,第一次加载时下一个箭头被禁用,并且它不会重新渲染实际数据的时间包括加载的行数。但是,如果您继续导航(例如更改页面大小),它就会变得可用,就像没有任何问题一样。 rowsPerPageOptions

我现在有点被这个问题困扰,我什至不知道我是否以正确的方式使用它。任何帮助将不胜感激。

import { useState, useEffect } from "react";
import { DataGrid } from "@material-ui/data-grid";
import { Box } from "@material-ui/core";

const dummyColorsDB = [
  { id: 1, color: "red" },
  { id: 2, color: "green" },
  { id: 3, color: "blue" },
  { id: 4, color: "violet" },
  { id: 5, color: "orange" },
  { id: 6, color: "burgundy" },
  { id: 7, color: "pink" },
  { id: 8, color: "yellow" },
  { id: 9, color: "magenta" },
  { id: 10, color: "random color" },
  { id: 11, color: "another random color" },
  { id: 12, color: "last one" }
];

export default function App() {
  const [data, setData] = useState({
    loading: true,
    rows: [],
    totalRows: 0,
    rowsPerPageOptions: [5, 10, 15],
    pageSize: 5,
    page: 1
  });

  const updateData = (k, v) => setData((prev) => ({ ...prev, [k]: v }));

  useEffect(() => {
    updateData("loading", true);

    setTimeout(() => {
      const rows = dummyColorsDB.slice(
        (data.page - 1) * data.pageSize,
        (data.page - 1) * data.pageSize + data.pageSize
      );

      console.log(rows);

      updateData("rows", rows);
      updateData("totalRows", dummyColorsDB.length);
      updateData("loading", false);
    }, 500);
  }, [data.page, data.pageSize]);

  return (
    <Box p={5}>
      <DataGrid
        density="compact"
        autoHeight
        rowHeight={50}
        //
        pagination
        paginationMode="server"
        loading={data.loading}
        rowCount={data.totalRows}
        rowsPerPageOptions={data.rowsPerPageOptions}
        page={data.page - 1}
        pageSize={data.pageSize}
        rows={data.rows}
        columns={[{ field: "color", headerName: "Color", flex: 1 }]}
        onPageChange={(data) => {
          updateData("page", data.page + 1);
        }}
        onPageSizeChange={(data) => {
          updateData("page", 1);
          updateData("pageSize", data.pageSize);
        }}
      />
    </Box>
  );
}
Run Code Online (Sandbox Code Playgroud)

Nea*_*arl 11

当您通过多次调用来更新组件状态时,如下所示:

updateData("rows", rows);
updateData("rowCount", dummyColorsDB.length);
updateData("loading", false);
Run Code Online (Sandbox Code Playgroud)

您的updateData调用setState但由于setState异步执行,因此它们不会同时更新。事实上,分页在第一次渲染时不起作用的原因是因为您rows在设置网格之前设置了网格rowCount。在检查代码库后,我的猜测是这是一个 Material-UI 错误。它们似乎没有添加state.options.rowCount到依赖项数组中useEffect,因此当您稍后更新时不会重新渲染任何内容rowCount

当您稍微推迟每次调用时,这一点会更清楚。下面的代码不起作用。

// set rows first
updateData("rows", rows);

setTimeout(() => {
  // set rowCount later
  updateData("rowCount", dummyColorsDB.length);
  updateData("loading", false);
}, 100);
Run Code Online (Sandbox Code Playgroud)

但尝试设置第rowCount一个,分页又可以工作了

// set rowCount first
updateData("rowCount", dummyColorsDB.length);

setTimeout(() => {
  updateData("rows", rows);
  updateData("loading", false);
}, 100);
Run Code Online (Sandbox Code Playgroud)

另一种解决方案是同时更新所有相关状态:

setData((d) => ({
  ...d,
  rowCount: dummyColorsDB.length,
  rows,
  loading: false
}));
Run Code Online (Sandbox Code Playgroud)

现场演示

编辑66950096/material-ui-datagrid-server-rendering-issue