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

如何在MUI X Data Grid的renderCell组件间传值实现Select联动

解决MUI X DataGrid中联动Select组件的状态传递问题

问题场景

在MUI X DataGrid中,新增行时第一列是选择文件的Select组件,第二列是选择参数的Select组件,要求参数的选项随选中的文件动态变化,但使用renderCell渲染组件时,两个组件的状态无法联动。

给定数据源:

const data = {
  "/path/to/file1.csv": {
    parameters: ["Parameter 1", "Parameter 2", "Parameter 3"],
  },
  "/path/to/file2.csv": {
    parameters: ["Parameter 2", "Parameter 3", "Parameter 4"],
  },
  "/path/to/file3.csv": {
    parameters: ["Parameter 5", "Parameter 6", "Parameter 7"],
  },
};

核心解决方案

将每行的选中状态(文件、参数)统一维护在rows数组中作为单一数据源。当文件选择变化时,更新对应行的选中文件,并同步更新该行的可选参数列表;参数选择变化时直接更新对应行的选中参数。通过修改rows触发DataGrid重新渲染,实现组件联动。

修改后的完整代码

import * as React from "react";
import PropTypes from "prop-types";
import { Button, Select, MenuItem } from "@mui/material";
import DeleteIcon from "@mui/icons-material/Delete";
import { DataGrid, GridActionsCellItem } from "@mui/x-data-grid";

const FileSelect = (props) => {
  const { params, files, data, updateRow } = props;
  const { row } = params;

  const handleChange = (event) => {
    const selectedFile = event.target.value;
    // 更新行的选中文件,同步可选参数并清空之前的参数选择
    updateRow(row.id, {
      selectedFile,
      availableParams: selectedFile ? data[selectedFile].parameters : [],
      selectedParam: ""
    });
  };

  return (
    <Select 
      value={row.selectedFile || ""} 
      onChange={handleChange} 
      fullWidth
      placeholder="选择文件"
    >
      {files.map((item, index) => (
        <MenuItem key={index} value={item}>
          {item}
        </MenuItem>
      ))}
    </Select>
  );
};

FileSelect.propTypes = {
  params: PropTypes.object.isRequired,
  files: PropTypes.array.isRequired,
  data: PropTypes.object.isRequired,
  updateRow: PropTypes.func.isRequired,
};

const ParameterSelect = (props) => {
  const { params, updateRow } = props;
  const { row } = params;

  const handleChange = (event) => {
    updateRow(row.id, { selectedParam: event.target.value });
  };

  return (
    <Select
      value={row.selectedParam || ""}
      onChange={handleChange}
      fullWidth
      disabled={!row.availableParams?.length}
      placeholder="选择参数"
    >
      {row.availableParams?.map((item, index) => (
        <MenuItem key={index} value={item}>
          {item}
        </MenuItem>
      ))}
    </Select>
  );
};

ParameterSelect.propTypes = {
  params: PropTypes.object.isRequired,
  updateRow: PropTypes.func.isRequired,
};

export default function DataGridTable(props) {
  const { data } = props;
  const files = Object.keys(data);

  const [rows, setRows] = React.useState([]);

  // 更新指定行数据的通用函数
  const updateRow = (rowId, updates) => {
    setRows(prevRows => 
      prevRows.map(row => 
        row.id === rowId ? { ...row, ...updates } : row
      )
    );
  };

  const columns = [
    {
      field: "file",
      headerName: "File",
      flex: 1,
      renderCell: (params) => (
        <FileSelect 
          params={params} 
          files={files} 
          data={data} 
          updateRow={updateRow} 
        />
      ),
    },
    {
      field: "x",
      headerName: "X",
      flex: 0.5,
      renderCell: (params) => (
        <ParameterSelect params={params} updateRow={updateRow} />
      ),
    },
    {
      field: "actions",
      headerName: "Delete",
      type: "actions",
      width: 80,
      getActions: (params) => [
        <GridActionsCellItem
          icon={<DeleteIcon />}
          label="Delete"
          onClick={() => deleteRow(params.id)}
        />,
      ],
    },
  ];

  const handleClick = () => {
    const newRow = {
      id: rows.length + 1,
      selectedFile: "",
      availableParams: [],
      selectedParam: ""
    };
    setRows(prevState => [...prevState, newRow]);
  };

  const deleteRow = (id) => {
    setRows(prevRows => prevRows.filter(row => row.id !== id));
  };

  return (
    <div>
      <Button variant="contained" onClick={handleClick}>
        Add row
      </Button>
      <div style={{ height: 300, width: "100%" }}>
        <DataGrid rows={rows} columns={columns} disableSelectionOnClick />
      </div>
    </div>
  );
}

关键修改点说明

  • 行数据结构优化:新增行时存储selectedFile(选中的文件)、availableParams(当前文件对应的可选参数)、selectedParam(选中的参数),不再将文件列表存入行数据。
  • 状态统一管理:移除两个Select组件内部的useState,改用rows中的行数据作为状态来源,通过updateRow函数统一更新行数据。
  • 联动逻辑实现:选中文件时,同步更新该行的availableParams,ParameterSelect会自动根据新的参数列表渲染选项,同时清空之前的参数选择。
  • 交互体验优化:当没有可选参数时,ParameterSelect自动禁用,避免无效操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 15:35:39