You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MUI DataGrid渲染完成后懒加载指定列数据?

实现MUI DataGrid表格渲染后延迟加载指定列数据

当然可以实现,核心是把数据请求从单元格渲染逻辑中剥离,避免在renderCell里直接发起请求(会触发大量重复请求、拖慢表格渲染),改用以下思路:

解决方案步骤

  1. 先加载表格核心数据(不含耗时的location列),完成表格渲染
  2. 监听表格渲染完成/可见行变化事件,批量发起location数据请求
  3. 用react-query管理请求状态与缓存,单元格根据缓存状态显示加载器或数据

代码示例(虚拟化表格场景,仅加载可见行数据)

import { DataGrid } from '@mui/x-data-grid';
import { useQuery } from '@tanstack/react-query';
import CircularProgress from '@mui/material/CircularProgress';
import { useEffect, useRef, useState } from 'react';

const MyDataGrid = () => {
  const gridRef = useRef(null);
  const [initialRows, setInitialRows] = useState([]);
  const [visibleRowIds, setVisibleRowIds] = useState([]);

  // 1. 加载表格核心数据(不含location)
  const { data: initialData } = useQuery({
    queryKey: ['gridInitialData'],
    queryFn: () => fetch('/api/grid-initial-data').then(res => res.json()),
  });

  useEffect(() => {
    if (initialData) setInitialRows(initialData);
  }, [initialData]);

  // 2. 监听可见行变化,仅加载当前屏幕内的行数据(适合虚拟化表格)
  const handleRowsVisibleChange = ({ params }) => {
    const ids = params.rows.map(row => row.id);
    setVisibleRowIds(ids);
  };

  // 3. 批量请求可见行的location数据
  const { data: locationData, isLoading: locationsLoading } = useQuery({
    queryKey: ['locationData', visibleRowIds],
    queryFn: () => fetch(`/api/locations?ids=${visibleRowIds.join(',')}`).then(res => res.json()),
    enabled: visibleRowIds.length > 0, // 有可见行时才发起请求
  });

  // 把返回数据转成id为key的映射,方便单元格快速查找
  const locationMap = locationData 
    ? Object.fromEntries(locationData.map(item => [item.id, item.location])) 
    : {};

  // 列配置
  const columns = [
    // 其他核心列...
    {
      field: "location",
      headerName: "Location",
      flex: 1,
      minWidth: 300,
      renderCell: (params) => {
        const location = locationMap[params.row.id];
        // 数据未就绪且正在加载时显示加载器
        if (!location && locationsLoading) {
          return <CircularProgress size={20} />;
        }
        // 显示数据或默认值
        return location || '暂无数据';
      },
    },
  ];

  return (
    <div style={{ height: 600, width: '100%' }}>
      <DataGrid
        ref={gridRef}
        rows={initialRows}
        columns={columns}
        onRowsVisibleChange={handleRowsVisibleChange}
        initialState={{
          pagination: { paginationModel: { page: 0, pageSize: 10 } },
        }}
        pageSizeOptions={[10, 20]}
      />
    </div>
  );
};

export default MyDataGrid;

非虚拟化场景(一次性加载所有行数据)

如果不需要虚拟化,可在表格核心数据加载完成后直接发起全量请求:

useEffect(() => {
  if (initialRows.length > 0) {
    setVisibleRowIds(initialRows.map(row => row.id));
  }
}, [initialRows]);

关键注意点

  • 后端API最好支持批量查询id(如/api/locations?ids=1,2,3),减少请求次数
  • 利用react-query的缓存机制,用户滚动回已加载的行时直接复用缓存,无需重复请求
  • 若后端不支持批量查询,可改用useQueries发起单个请求,但需注意控制并发量

内容的提问来源于stack exchange,提问作者Abasaheb Gaware

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 18:35:22