reactjs 添加具有选择字段的新行作为单元格

wz3gfoph  于 2023-06-29  发布在  React
关注(0)|答案(1)|浏览(111)

我正在使用MUI库中的DataGrid。我有一个包含四个单元格的表(id:number,processPath:选择字段,关联登录:文本字段,操作:我还添加了在单击按钮时添加和删除行的功能。我面临的问题是名为processPath的列,单元格采用SelectField,更新值,但每次我添加新行时,它都会保留前一行的值。我之所以选择包括其他列,是因为我希望回答问题的人有完整的范围,以及我的数据结构的原因。我的问题是,我有一个UDF函数组件,我正在handleAddRow上重用它,但我不知道如何将下一行的状态更新为空。

import {
  FormControl,
  InputLabel,
  MenuItem,
  Select,
  SelectChangeEvent,
  Box,
  Button,
  Stack,
} from "@mui/material";
import {
  DataGrid,
} from "@mui/x-data-grid";
import React, { FunctionComponent, useState } from "react";

const processPaths: string[] = ["Test1", "Test2"];

export const AccomodationsTable: FunctionComponent = () => {
  const [idCounter, setIdCounter] = useState(0);
  const [rowCounter, setRowCounter] = useState(0);

  const [formData, setFormData] = useState([
    {
      id: idCounter,
      processPath: "",
      associateLogin: "",
      action: "",
    },
  ]);

  const ProcessPathSelectField: FunctionComponent = () => {
    function handleChange(event: SelectChangeEvent) {
      const { name, value } = event.target;
      setFormData((prevFormData) => ({
        ...prevFormData,
        [name]: value,
      }));
    }

    return (
      <Box>
        <FormControl fullWidth>
          <InputLabel id={`process-path-select-${idCounter}`}>
            Please Select
          </InputLabel>
          <Select
            labelId="process-path-select"
            id={`process-path-select-${idCounter}`}
            value={formData[0].processPath}
            name="processPath"
            label={`process-path-select-${idCounter}`}
            onChange={handleChange}
            sx={{ minWidth: "240px" }}
          >
            {processPaths.sort().map((processPath) => (
              <MenuItem value={processPath}>{processPath}</MenuItem>
            ))}
          </Select>
        </FormControl>
      </Box>
    );
  };

  const createNewRow = () => {
    setIdCounter((prevIdCounter) => (prevIdCounter + 1));
    return {
      id: idCounter,
      processPath: "",
      associateLogin: "",
      action: "",
    };
  };

  const [rows, setRows] = useState(() => [createNewRow()]);

  const handleAddRow = () => {
    setRows((prevRows) => [...prevRows, createNewRow()]);
  };

  const handleRemoveRow = () => {
    setRows(rows.slice(0, idCounter - 1));
    setIdCounter((prevIdCounter) => (prevIdCounter - 1));
  };

  const columns = [
    { field: "id" },
    {
      field: "Process Path",
      width: 270,
      renderCell: () => <ProcessPathSelectField />,
    },
    { field: "Associate Login", width: 270 },
    { field: "Action", width: 270 },
  ];

  return (
    <>
      <Box sx={{ width: "100%" }}>
        <Stack direction="row" spacing={1} sx={{ mb: 1 }}>
          <Button size="small" onClick={handleRemoveRow}>
            Remove a row
          </Button>
          <Button size="small" onClick={handleAddRow}>
            Add a row
          </Button>
        </Stack>
        <Box sx={{ height: 400, mt: 1 }}>
          <DataGrid
            rows={rows}
            columns={columns}
            columnVisibilityModel={{
              id: false,
            }}
          />
        </Box>
      </Box>
    </>
  );
};
ttcibm8c

ttcibm8c1#

您正在使用自定义组件(ProcessPathSelectField)呈现processPath列的单元格。这可能会导致数据网格的内部状态管理出现一些问题,因为它需要一个从网格接收值和onChange属性的受控组件。您可能希望使用内置的GridRenderEditCellParams接口来访问这些props并将它们传递给Select组件。像这样:

import { DataGrid, GridRenderEditCellParams } from "@mui/x-data-grid";

const ProcessPathSelectField: FunctionComponent<GridRenderEditCellParams> = (
  params
) => {
  return (
    <Box>
      <FormControl fullWidth>
        <InputLabel id={`process-path-select-${params.id}`}>
          Please Select
        </InputLabel>
        <Select
          labelId="process-path-select"
          id={`process-path-select-${params.id}`}
          value={params.value}
          name="processPath"
          label={`process-path-select-${params.id}`}
          onChange={params.onChange}
          sx={{ minWidth: "240px" }}
        >
          {processPaths.sort().map((processPath) => (
            <MenuItem value={processPath}>{processPath}</MenuItem>
          ))}
        </Select>
      </FormControl>
    </Box>
  );
};

相关问题