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

Material UI DataGrid不显示:需等待useEffect完成数据加载

问题:Material UI DataGrid 表格无法显示,数据加载完成后仍无输出

表格无法显示,但数据会在几秒后加载完成。使用Material UI的DataGrid组件,控制台出现错误,推测是页面渲染时fetch请求尚未完成导致的。

错误信息

错误信息截图

列数据与表格数据格式

数据格式截图

我的JSX代码

import { DataGrid, GridColDef, GridValueGetterParams } from '@mui/x-data-grid';
import React, { useState, useEffect } from 'react';
import { getNameOfJSDocTypedef, WatchDirectoryFlags } from '../../../node_modules/typescript/lib/typescript';


// ==============================|| MOB ||============================== //

let first_run = true;

var columns = [];
var rows = [];
const Mob = () => {
  
  const [antDataColumns, setAntDataColumns] = useState([]);
  const urlAntColumns = "QUERYURL";

  const [antData, setAntData] = useState([]);
  const urlAnt = 'QUERYURL';


  useEffect(() => {
    fetch(urlAntColumns)
      .then((response) => {
        return response.json();
      })
      .then((data) => {
        setAntDataColumns(data);
      });
  }, []);

  useEffect(() => {
    fetch(urlAnt)
      .then((response) => {
        return response.json();
      })
      .then((data) => {
        setAntData(data);
      });
  }, []);
  if (antDataColumns.length > 0 && antData.length > 0 && first_run === true) {
    columns.push({ field: 'id', headerName: 'ID', width: 70 })
    for (let i = 6; i < 12; i++){
      columns.push({field: antDataColumns[i]['column_name'], headerName: antDataColumns[i]['column_name'], width: 70});
    }
    for (let i = 0; i < 20; i++){
      let row = {};
      row["id"] = i+1;
      for (let j = 1; j < columns.length; j++) {
        row[columns[j]['field']] = antData[i][columns[j]['field']];
      }
      rows.push(row);
    }
    first_run = false;
    }
    console.log("---------------------------------------------------------------------------------------------------------")
    console.log(columns)
    
    

    console.log("---")


    console.log(rows)
    

    console.log("---------------------------------------------------------------------------------------------------------")
    
    return (
      <div style={{ height: 1000, width: '100%' }}>
  <DataGrid
    rows={rows}
    columns={columns}
    pageSize={10}
    rowsPerPageOptions={[10]}
    checkboxSelection
  />
</div>
    )

    
};

export default Mob;

解决方法

核心问题是你用了组件外部的变量columns、rows和first_run存储状态,这些变量不属于React状态管理体系,数据更新后不会触发组件重新渲染,导致DataGrid拿不到最新数据。按React规范修改如下:

修改后的代码

import { DataGrid, GridColDef, GridValueGetterParams } from '@mui/x-data-grid';
import React, { useState, useEffect } from 'react';

const Mob = () => {
  const [antDataColumns, setAntDataColumns] = useState([]);
  const [antData, setAntData] = useState([]);
  // 将columns、rows转为组件内部状态
  const [columns, setColumns] = useState([]);
  const [rows, setRows] = useState([]);
  // 用状态跟踪数据是否已处理,替代外部的first_run
  const [hasProcessedData, setHasProcessedData] = useState(false);

  const urlAntColumns = "QUERYURL";
  const urlAnt = 'QUERYURL';

  useEffect(() => {
    fetch(urlAntColumns)
      .then((response) => response.json())
      .then((data) => setAntDataColumns(data));
  }, []);

  useEffect(() => {
    fetch(urlAnt)
      .then((response) => response.json())
      .then((data) => setAntData(data));
  }, []);

  // 当两个接口数据都加载完成且未处理过时,生成列和行数据
  useEffect(() => {
    if (antDataColumns.length > 0 && antData.length > 0 && !hasProcessedData) {
      const newColumns = [{ field: 'id', headerName: 'ID', width: 70 }];
      // 生成列配置
      for (let i = 6; i < 12; i++) {
        newColumns.push({
          field: antDataColumns[i]['column_name'],
          headerName: antDataColumns[i]['column_name'],
          width: 70
        });
      }
      // 生成行数据
      const newRows = [];
      for (let i = 0; i < 20; i++) {
        const row = { id: i + 1 };
        for (let j = 1; j < newColumns.length; j++) {
          row[newColumns[j]['field']] = antData[i][newColumns[j]['field']];
        }
        newRows.push(row);
      }
      // 更新状态触发组件重新渲染
      setColumns(newColumns);
      setRows(newRows);
      setHasProcessedData(true);
    }
  }, [antDataColumns, antData, hasProcessedData]);

  return (
    <div style={{ height: 1000, width: '100%' }}>
      <DataGrid
        rows={rows}
        columns={columns}
        pageSize={10}
        rowsPerPageOptions={[10]}
        checkboxSelection
      />
    </div>
  )
};

export default Mob;

关键修改说明

  • 把组件外部的变量全部换成React的useState状态,确保数据变化时自动触发组件重新渲染
  • 将数据处理逻辑移到useEffect中,依赖antDataColumns、antData和hasProcessedData,保证只有在两个接口都返回数据且未处理过时才执行生成逻辑
  • 移除无用的typescript导入,避免不必要的依赖问题
  • 用const替代var,符合现代JavaScript规范

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 05:40:41