跳到内容
+

数据网格 - 服务器端数据 🧪

数据网格服务器端数据。

介绍

在 React 中,随着数据集的增长,服务器端数据管理可能会变得复杂。挑战包括手动数据获取、分页、排序、筛选和性能优化。专用模块可以帮助抽象这些复杂性,从而改善用户体验。

考虑一个显示用户列表的数据网格。它支持分页、按列标题排序和筛选。当用户更改页面或更新筛选或排序时,数据网格从服务器获取数据。

const [rows, setRows] = React.useState([]);
const [paginationModel, setPaginationModel] = React.useState({
  page: 0,
  pageSize: 10,
});
const [filterModel, setFilterModel] = React.useState({ items: [] });
const [sortModel, setSortModel] = React.useState([]);

React.useEffect(() => {
  const fetcher = async () => {
    // fetch data from server
    const data = await fetch('https://my-api.com/data', {
      method: 'GET',
      body: JSON.stringify({
        page: paginationModel.page,
        pageSize: paginationModel.pageSize,
        sortModel,
        filterModel,
      }),
    });
    setRows(data.rows);
  };
  fetcher();
}, [paginationModel, sortModel, filterModel]);

<DataGridPro
  columns={columns}
  pagination
  sortingMode="server"
  filterMode="server"
  paginationMode="server"
  onPaginationModelChange={setPaginationModel}
  onSortModelChange={setSortModel}
  onFilterModelChange={setFilterModel}
/>;

此示例仅触及表面,仍有许多问题尚未解决,例如

  • 性能优化
  • 缓存数据/请求去重
  • 服务器上更复杂的用例,例如分组、树状数据等。
  • 服务器端行编辑
  • 数据懒加载
  • 处理数据更新,例如行编辑、行删除等。
  • 按需重新获取数据

尝试逐个解决这些问题可能会使代码变得复杂且难以维护。

数据源

集中式数据源的想法是为了简化服务器端数据获取。它是数据网格和服务器之间的抽象层,为与服务器交互提供了一个简单的接口。可以将其视为处理数据网格(客户端)和实际数据源(服务器)之间通信的中间层。

它有一组需要实现的初始必需方法。数据网格将在内部使用这些方法在需要时获取数据子集。

让我们看一下最小的 GridDataSource 接口配置。

interface GridDataSource {
  /**
   * This method will be called when the grid needs to fetch some rows.
   * @param {GridGetRowsParams} params The parameters required to fetch the rows.
   * @returns {Promise<GridGetRowsResponse>} A promise that resolves to the data of
   * type [GridGetRowsResponse].
   */
  getRows(params: GridGetRowsParams): Promise<GridGetRowsResponse>;
}

以下是使用数据源实现上述示例的样子

const customDataSource: GridDataSource = {
  getRows: async (params: GridGetRowsParams): GetRowsResponse => {
    const response = await fetch('https://my-api.com/data', {
      method: 'GET',
      body: JSON.stringify(params),
    });
    const data = await response.json();

    return {
      rows: data.rows,
      rowCount: data.totalCount,
    };
  },
}

<DataGridPro
  columns={columns}
  unstable_dataSource={customDataSource}
  pagination
/>

代码已大大减少,无需管理受控状态,并且数据获取逻辑已集中化。

服务器端筛选、排序和分页

数据源改变了现有服务器端功能(如 filteringsortingpagination)的工作方式。

没有数据源

当没有数据源时,筛选、排序、分页功能默认在客户端工作。为了使它们与服务器端数据一起工作,您需要显式地将它们设置为 server,并提供 onFilterModelChangeonSortModelChangeonPaginationModelChange 事件处理程序,以便根据更新的变量从服务器获取数据。

<DataGrid
  columns={columns}
  rows={rows}
  pagination
  sortingMode="server"
  filterMode="server"
  paginationMode="server"
  onPaginationModelChange={(newPaginationModel) => {
    // fetch data from server
  }}
  onSortModelChange={(newSortModel) => {
    // fetch data from server
  }}
  onFilterModelChange={(newFilterModel) => {
    // fetch data from server
  }}
/>

使用数据源

使用数据源,筛选、排序、分页功能会自动设置为服务器端。

当相应的模型更新时,数据网格会使用类型为 GridGetRowsParams 的更新值调用 getRows 方法,以获取更新的数据。

<DataGridPro
  columns={columns}
  // automatically sets `sortingMode="server"`, `filterMode="server"`, `paginationMode="server"`
  unstable_dataSource={customDataSource}
/>

以下演示展示了此行为。

Enter 开始编辑

数据缓存

数据源默认缓存获取的数据。这意味着,如果用户导航到已获取的页面或展开已获取的节点,网格将不再调用 getRows 函数,以避免不必要地调用服务器。

默认使用 GridDataSourceCacheDefault,这是一个简单的内存缓存,将数据存储在普通对象中。可以在上面的演示中看到它的实际效果。

自定义缓存生命周期

GridDataSourceCacheDefault 的默认生存时间 (ttl) 为 5 分钟。要自定义它,请将 ttl 选项(以毫秒为单位)传递给 GridDataSourceCacheDefault 构造函数,然后将其作为 unstable_dataSourceCache 属性传递。

import { GridDataSourceCacheDefault } from '@mui/x-data-grid-pro';

const lowTTLCache = new GridDataSourceCacheDefault({ ttl: 1000 * 10 }); // 10 seconds

<DataGridPro
  columns={columns}
  unstable_dataSource={customDataSource}
  unstable_dataSourceCache={lowTTLCache}
/>;
Enter 开始编辑

自定义缓存

要提供自定义缓存,请使用 unstable_dataSourceCache 属性,它可以是从头编写的,也可以基于另一个缓存库。此属性接受 GridDataSourceCache 类型的通用接口。

export interface GridDataSourceCache {
  set: (key: GridGetRowsParams, value: GridGetRowsResponse) => void;
  get: (key: GridGetRowsParams) => GridGetRowsResponse | undefined;
  clear: () => void;
}

禁用缓存

要禁用数据源缓存,请将 null 传递给 unstable_dataSourceCache 属性。

<DataGridPro
  columns={columns}
  unstable_dataSource={customDataSource}
  unstable_dataSourceCache={null}
/>
Enter 开始编辑

错误处理

您可以使用数据源的错误处理程序函数 unstable_onDataSourceError 来处理错误。每当获取数据时发生错误,就会调用它。

此函数的第一个参数是错误对象,第二个参数是类型为 GridGetRowsParams 的获取参数。

<DataGridPro
  columns={columns}
  unstable_dataSource={customDataSource}
  unstable_onDataSourceError={(error, params) => {
    console.error(error);
  }}
/>

更新数据 🚧

此功能尚未实现,完成后,每当用户编辑行时,都会使用 GridRowModel 调用方法 unstable_dataSource.updateRow。它的工作方式与 processRowUpdate 属性类似。

欢迎为相关的 GitHub 问题投赞成票,以更快地看到此功能落地。

API