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

MUIDataTables编辑按钮点击无弹窗问题求助

问题描述

我使用MUIDataTables实现编辑和新增记录功能,点击「新建」按钮时模态框能正常弹出,但点击「编辑」按钮时模态框无反应。需要在模态框中展示待编辑记录,并提供保存、取消功能。附上相关代码,恳请帮助。

相关代码
import React, { useEffect, useState } from "react";
import ReactDOM from "react-dom";
import MUIDataTable from "mui-datatables";

import {
  Button,
  Select,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogContentText,
  TextField,
  DialogActions
} from "@mui/material";

function ModalBox({ open, handleClose, handleSave, selectedData }) {
  const [state, setState] = useState({
    dname: "",
    dsource: ""
  });

  useEffect(() => {
    if (selectedData) {
      setState({
        dname: selectedData[1],
        dsource: selectedData[2]
      });
    } else {
      // 新建时清空表单
      setState({ dname: "", dsource: "" });
    }
  }, [selectedData]);

  const handleChange = (e) => {
    const { name, value } = e.target;
    setState((prevState) => ({
      ...prevState,
      [name]: value
    }));
  };

  const handleEditSave = () => {
    handleSave(state.dname, state.dsource);
  };

  return (
    <div>
      <Dialog open={open} onClose={handleClose} aria-labelledby="form-dialog-title">
        <DialogTitle id="form-dialog-title">{selectedData ? "编辑行" : "新建行"}</DialogTitle>
        <DialogContent>
          <DialogContentText>
            {selectedData ? "请输入新的值来编辑此行。" : "请输入新记录的信息。"}
          </DialogContentText>
          <TextField
            autoFocus
            margin="dense"
            id="name"
            name="dname"
            label="名称"
            type="text"
            value={state.dname}
            onChange={handleChange}
            fullWidth
          />
          <TextField
            margin="dense"
            id="provider"
            name="dsource"
            label="供应商"
            type="text"
            value={state.dsource}
            onChange={handleChange}
            fullWidth
          />
        </DialogContent>
        <DialogActions>
          <Button onClick={handleClose} color="primary">
            取消
          </Button>
          <Button onClick={handleEditSave} color="primary">
            保存
          </Button>
        </DialogActions>
      </Dialog>
    </div>
  );
}

function Companies() {
  const columns = [
    {
      name: "编辑",
      options: {
        filter: false,
        sort: false,
        empty: true,
        customBodyRender: (value, tableMeta, updateValue) => (
          <Button
            variant="contained"
            color="primary"
            onClick={() => {
              const selectedRow = tableMeta.rowData;
              setEditModalOpen(true);
              setSelectedData(selectedRow);
            }}
          >
            编辑
          </Button>
        ),
      },
    },
    "ID",
    "名称",
    "供应商",
  ];
  const [data, setData] = useState([]);
  const [id, setId] = useState(0);

  function createData(name, provider) {
    const newId = id + 1;
    setId(newId);
    return [newId, name, provider];
  }

  useEffect(() => {
    const initialData = [
      createData("Dummy1", "oracle"),
      createData("Dummy2", "mssql"),
      createData("Dummy3", "oracle"),
    ];
    setData(initialData);
  }, []);

  const options = {
    filterType: "checkbox",
  };

  const [editModalOpen, setEditModalOpen] = useState(false);
  const [selectedData, setSelectedData] = useState(null);

  const handleSave = (dname, dsource) => {
    if (selectedData) {
      // 编辑逻辑:更新对应行
      const updatedData = data.map((row) => {
        if (row[0] === selectedData[0]) {
          return [row[0], dname, dsource];
        }
        return row;
      });
      setData(updatedData);
    } else {
      // 新建逻辑:添加新行
      const newRow = createData(dname, dsource);
      setData([...data, newRow]);
    }
    setEditModalOpen(false);
    setSelectedData(null);
  };

  return (
    <div className="f-height fx-column-cont">
      <div>
        {/* 新建按钮 */}
        <Button
          variant="contained"
          color="secondary"
          onClick={() => {
            setSelectedData(null);
            setEditModalOpen(true);
          }}
          style={{ marginBottom: 16 }}
        >
          新建
        </Button>
        <ModalBox
          open={editModalOpen}
          handleClose={() => setEditModalOpen(false)}
          handleSave={handleSave}
          selectedData={selectedData}
        />
        <MUIDataTable
          title="测试数据源"
          data={data}
          columns={columns}
          options={options}
        />
      </div>
    </div>
  );
}

export default Companies;
问题分析与修复方案

核心问题:编辑按钮无法触发模态框

你的代码中,Edit列的customBodyRender使用value参数查找行数据,但Edit列配置了empty: true,导致value为undefined,data.find(row => row[0] === value)找不到对应行,selectedRow为undefined。虽然执行了setEditModalOpen(true),但模态框无法加载数据,甚至可能因为状态更新异常导致显示失败。

修复步骤:

  1. 修改编辑按钮的行数据获取逻辑:
    直接通过tableMeta.rowData获取当前行的完整数据,无需通过value查找,修改后的customBodyRender代码已包含在上面的完整代码中。

  2. 完善新建功能:

    • 在表格上方添加新建按钮,点击时清空selectedData并打开模态框
    • 修改ModalBox的标题和提示文本,区分编辑与新建场景
    • 更新handleSave函数,添加新建记录的逻辑
  3. 修复ID生成问题:
    原代码中let id = 0;是组件内变量,每次渲染都会重置,导致新建记录ID可能重复。改用useState管理ID状态,确保ID递增正确。

修复后效果

  • 点击「编辑」按钮,模态框正常弹出并加载对应行的数据
  • 点击「新建」按钮,模态框弹出空表单,输入后保存可新增记录
  • 保存后表格数据实时更新,模态框自动关闭

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 13:42:07