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
相关产品推荐
相关产品推荐

