Material UI:使用swr时DataGrid服务器端分页数据闪烁

问题描述 投票:0回答:1

我想在 Material UI DataGrid 上显示服务器端分页数据,并使用 swr 获取数据。我一直在研究 DataGrid 中服务器端数据的 MUI 介绍示例,它使用

useEffect
钩子来获取数据,但我已经对其进行了调整
swr
这是我的代码的相关部分

const [paginationModel, setPaginationModel] = useState({
  page: 0,
  pageSize: 3,
});

const fetcher = (url: RequestInfo) => fetch(url).then((res) => res.json());

const { data, error, isLoading, mutate } = useSWR(
    `http://localhost:3002/ingredients/pagination?page=${paginationModel.page}&pageSize=${paginationModel.pageSize}`,
    fetcher
  );

const rowCountRef = useRef(data?.rowCount || 0);

const rowCount = useMemo(() => {
  if (data?.rowCount !== undefined) {
    rowCountRef.current = data.rowCount;
  }
  return rowCountRef.current;
}, [data?.rowCount]);

return (
  <Box sx={{ height: 400, width: "100%" }}>
    <DataGrid
      rows={data?.data ?? []}
      rowCount={rowCount}
      columns={columns}
      loading={loading}
      initialState={{
        pagination: {
          paginationModel: {
            pageSize: 5,
          },
        },
      }}
      pageSizeOptions={[3, 5, 10, 50]}
      disableRowSelectionOnClick
      pagination
      paginationMode="server"
      paginationModel={paginationModel}
      onPaginationModelChange={setPaginationModel}
    />
    <Button onClick={buttonHandler}>Post</Button>
  </Box>
);

我的分页端点返回 json,其中包含一个包含成分元素的

data
字段和一个包含总行数的
rowCount
字段。

我目前所拥有的大部分工作正常,但在某些条件下我看到总行数以及行数据闪烁。

问题场景发生在这些条件下

  1. 对几个页面进行分页以“缓存”这些页面。
  2. 添加新记录。
  3. 切换到表中您已访问过的其他页面,在更新为新值之前,总计会暂时显示旧值(由于添加了新记录,因此应该为 +1)。这将发生在您已经访问过的每个页面上。如果这些缓存页面之一上的行已更改,它也将显示旧行,直到从后端拉入新数据。请参阅此处
  4. 的简短视频演示

如果我改用 React 的

useEffect
钩子来进行服务器端分页,这个问题似乎不会发生。分页到新页面时,会显示旧的
rowCount
,直到网络请求返回新的总计数,并且
rowCount
相应更新。之后访问后续页面不会出现使用
swr

时出现的任何闪烁问题

我认为这与缓存问题有关,但我无法理解具体发生了什么。我觉得奇怪的是,对于表中的每个“缓存”页面,

rowCount
属性都持有看似特定于每个页面的缓存值,但
DataGrid
组件本身却有一个单一的
rowCount
属性。我假设第一次重新验证数据时,会计算最新的
rowCount
值,并且后续页面将准确显示,但事实并非如此。

任何人都可以对此提供见解吗?是否有更优雅的方法来处理传入的新数据?在正确的数据流入之前暂时显示缓存的值感觉就像糟糕的用户体验。

链接到代码沙箱

代码沙箱并没有完全实现上面的代码,因为我必须模拟网络请求,但它相当相似。沙箱使用

useEffect
钩子和
swr
实现服务器端分页。要在每种方法之间切换,您需要注释/取消注释
rows
rowCount
loading
的属性(第 97-104 行)

reactjs react-hooks material-ui swr mui-x-data-grid
1个回答
0
投票

我没有看到任何数据“闪烁”。我所看到的是您向数据添加了一条记录,这增加了行数总数。当您返回上一页时,我看到页面数据被重新验证once,然后总数据行计数更新once以反映当前总计数。

当我切换到您的

useEffect
逻辑时,我在切换页面时看到一个加载指示器。如果这就是您在使用
useSWR
挂钩时想要的全部内容,那么我建议在加载分页数据以及重新验证数据时也使用返回的
isValidating
状态来显示/渲染加载 UI。

const {
  data: swrData,
  error,
  isLoading,
  isValidating, // <--
  mutate,
} = useSWR(
  `pagination?page=${paginationModel.page}&pageSize=${paginationModel.pageSize}`,
  fetcher
);

...

<DataGrid
  rows={swrData?.data ?? []}
  rowCount={rowCount}
  loading={isLoading || isValidating} // <-- loading or validating
  density="compact"
  autoHeight
  rowHeight={50}
  pagination
  paginationMode="server"
  pageSizeOptions={[3, 5, 10, 15]}
  paginationModel={paginationModel}
  columns={[
    { field: "id" },
    { field: "color", headerName: "Color", flex: 1 },
  ]}
  onPaginationModelChange={setPaginationModel}
  initialState={{
    sorting: {
      sortModel: [{ field: "id", sort: "desc" }],
    },
  }}
/>
© www.soinside.com 2019 - 2024. All rights reserved.