React MUI X Data Grid结合Axios获取选中行数据报错排查
问题描述
我参考示例为@mui/x-data-grid添加选中行功能,以获取选中行的完整数据。示例用useDemoData填充表格,我则通过Axios调用API获取行数据并使用预配置列。代码如下:
import React, { useState, useEffect } from 'react'; import axios from "axios"; import { DataGrid, GridToolbar } from '@mui/x-data-grid'; const columns = [ { field: 'id', headerName: 'Job ID', width: 170 }, { field: 'file_name', headerName: 'File Name', width: 250 }, { field: 'product_type', headerName: 'Product Type', width: 300 }, { field: 'status', headerName: 'Status', width: 170, editable: true }, ]; function QueueMgrTable() { const [data, setData] = useState([]); const [loadingData, setLoadingData] = useState(true); const [selectedRows, setSelectedRows] = useState([]); async function getData() { await axios .get('https://myendpoint.com/test/jobs', { headers: { 'Content-Type': 'application/json' } }) .then((response) =>{ var test_data = response.data.data; setData( test_data.map((x) => { return { id: parseInt(`${x.job_id}`), file_name: `${x.file_name}`, product_type: `${x.product_type}`, status: `${x.status}` } }) ); setLoadingData(false); }); } useEffect((data) => { console.log(config); getData(); if (loadingData) { getData(); } }, []); return ( <div style={{ height: 600, width: '100%' }}> {loadingData ? ( <p>Loading. Please wait...</p> ) : ( <DataGrid columns={columns} pageSize={20} rowsPerPageOptions={[10]} checkboxSelection components={{ Toolbar: GridToolbar }} onSelectionModelChange={(ids) => { const selectedIDs = new Set(ids); const selectedRows = data.rows.filter((row) => selectedIDs.has(row.id), ); setSelectedRows(selectedRows); }} rows={data} /> )} <pre style={{ fontSize: 10 }}> {JSON.stringify(selectedRows, null, 4)} </pre> </div> ); }; export default QueueMgrTable;
点击行时出现报错,报错提示Cannot read properties of undefined (reading 'filter'),怀疑是state导致data未定义时执行了filter操作,想知道哪里出错了。
错误原因与修复方案
1. 核心错误:错误访问data.rows
你的data状态本身就是行数据数组(初始值为[],API返回后也是映射后的数组),但在onSelectionModelChange里错误写成了data.rows.filter,直接调用data.filter即可。
2. 其他潜在问题修复
- useEffect冗余调用:原
useEffect回调函数参数错误,还调用了两次getData,且存在未定义的config变量,需清理。 - API错误处理:原Axios请求未做错误捕获,需添加
catch处理请求失败场景。 - parseInt安全处理:给
parseInt加上基数10,避免解析非十进制字符串时出现意外。
修复后的完整代码
import React, { useState, useEffect } from 'react'; import axios from "axios"; import { DataGrid, GridToolbar } from '@mui/x-data-grid'; const columns = [ { field: 'id', headerName: 'Job ID', width: 170 }, { field: 'file_name', headerName: 'File Name', width: 250 }, { field: 'product_type', headerName: 'Product Type', width: 300 }, { field: 'status', headerName: 'Status', width: 170, editable: true }, ]; function QueueMgrTable() { const [data, setData] = useState([]); const [loadingData, setLoadingData] = useState(true); const [selectedRows, setSelectedRows] = useState([]); async function getData() { try { const response = await axios.get('https://myendpoint.com/test/jobs', { headers: { 'Content-Type': 'application/json' } }); const test_data = response.data.data; setData( test_data.map((x) => ({ id: parseInt(x.job_id, 10), file_name: x.file_name, product_type: x.product_type, status: x.status })) ); setLoadingData(false); } catch (error) { console.error('获取数据失败:', error); setLoadingData(false); } } useEffect(() => { getData(); }, []); return ( <div style={{ height: 600, width: '100%' }}> {loadingData ? ( <p>加载中,请稍候...</p> ) : ( <DataGrid columns={columns} pageSize={20} rowsPerPageOptions={[10]} checkboxSelection components={{ Toolbar: GridToolbar }} onSelectionModelChange={(ids) => { const selectedIDs = new Set(ids); const selectedRows = data.filter((row) => selectedIDs.has(row.id)); setSelectedRows(selectedRows); }} rows={data} /> )} <pre style={{ fontSize: 10 }}> {JSON.stringify(selectedRows, null, 4)} </pre> </div> ); }; export default QueueMgrTable;
关键修复点说明
- 替换
data.rows.filter为data.filter,因为data本身就是行数据数组。 - 清理
useEffect冗余代码,仅在组件挂载时调用一次getData。 - 添加Axios请求错误捕获,避免请求失败时页面一直处于加载状态。
- 移除不必要的模板字符串包裹,简化代码逻辑。
内容的提问来源于stack exchange,提问作者gwydion93
相关产品推荐
相关产品推荐

