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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 09:11:21