MUI DataTable数据已更新但不显示,出现forEach未定义报错
问题分析与解决方案
核心问题拆解
useEffect依赖错误导致无限循环+状态更新失效
你的useEffect依赖写的是[data],但逻辑是loadingData为true时调用getData,这会导致每次data更新就触发useEffect,重复调用getData;同时setData是异步操作,if (Object.keys(data).length > 0)判断的还是旧的空数组,setLoadingData(false)根本不会执行,表格一直卡在加载状态,就算拿到数据也不会渲染。DataTable报错根源
报错Cannot read properties of undefined (reading 'forEach'),是因为useTable接收的data变成了非数组类型(比如接口返回对象而非数组,或者状态更新异常导致data为undefined),无法执行forEach遍历。列配置字段匹配错误
你的columns里Opco Type和Session Route Limit的accessor写反了,会导致表格列数据显示异常。
具体修复步骤
1. 修正useEffect依赖与loading状态更新逻辑
把useEffect依赖改为[loadingData],同时直接用接口返回的数据判断状态,不用等待React state异步更新:
async function getData() { try { const response = await Axios.get("http://localhost:8080/table/latesttest"); console.log(response.data); // 确保数据是数组格式,避免非数组传入表格导致报错 const tableData = Array.isArray(response.data) ? response.data : []; setData(tableData); // 直接用返回的新数据判断,无需等待state更新 if (tableData.length > 0) { setLoadingData(false); } } catch (err) { console.error("获取数据失败:", err); setLoadingData(false); } } useEffect(() => { if (loadingData) { getData(); } }, [loadingData]); // 依赖改为loadingData,避免无限循环调用接口
2. 修正列配置的accessor字段
把写反的字段调整回来,确保和接口返回的字段匹配:
const columns = [ { Header: "Region ID", accessor: "region_id", width: "1%", align: "left" }, { Header: "Region Name", accessor: "opco_name", align: "left" }, { Header: "Opco Type", accessor: "opco_type", align: "left" }, // 修正字段 { Header: "Session Route Limit", accessor: "RN_session_route_limit", align: "left" }, // 修正字段 { Header: "Avg Routes", accessor: "prev_average_routes", align: "left" }, { Header: "Max Routes", accessor: "prev_differ_average", align: "left" }, { Header: "Diff Average", accessor: "prev_differ_max", align: "left" }, { Header: "Diff Max", accessor: "current_average_routes", align: "left" }, ];
3. 强制更新表格的兜底方案
如果以上修复后表格仍不更新,可以给DataTable添加动态key,强制React重新渲染组件:
{loadingData ? <p>Loading Please Wait...</p> : <DataTable key={data.length} table={{ columns, data }} />}
最终修复后的完整代码
import React, { useEffect, useState } from "react"; import Axios from "axios"; import DataTable from "examples/Tables/DataTable"; function LicenseTable() { const [loadingData, setLoadingData] = useState(true); const [data, setData] = useState([]); const columns = [ { Header: "Region ID", accessor: "region_id", width: "1%", align: "left" }, { Header: "Region Name", accessor: "opco_name", align: "left" }, { Header: "Opco Type", accessor: "opco_type", align: "left" }, { Header: "Session Route Limit", accessor: "RN_session_route_limit", align: "left" }, { Header: "Avg Routes", accessor: "prev_average_routes", align: "left" }, { Header: "Max Routes", accessor: "prev_differ_average", align: "left" }, { Header: "Diff Average", accessor: "prev_differ_max", align: "left" }, { Header: "Diff Max", accessor: "current_average_routes", align: "left" }, ]; async function getData() { try { const response = await Axios.get("http://localhost:8080/table/latesttest"); console.log(response.data); const tableData = Array.isArray(response.data) ? response.data : []; setData(tableData); if (tableData.length > 0) { setLoadingData(false); } } catch (error) { console.error("数据加载失败:", error); setLoadingData(false); } } useEffect(() => { if (loadingData) { getData(); } }, [loadingData]); return ( <div className="App"> {loadingData ? ( <p>Loading Please Wait...</p> ) : ( <DataTable key={data.length} table={{ columns, data }} /> )} </div> ); } export default LicenseTable;
内容的提问来源于stack exchange,提问作者Brithivi keshan
相关产品推荐
相关产品推荐

