在 cellRender 中使用复选框时如何更改 MUI 数据网格的状态?

How do I change state of MUI Data Grid when using a checkbox in cellRender?

所以我有一个相当简单的场景,我正在处理我需要 MUI 数据网格中的复选框,但不使用 checkboxSelection。我很容易在一列中呈现我的复选框,但是一旦我选中该框,我就无法真正弄清楚如何更改该网格行的状态。该函数接收事件对象,您可以访问目标元素,但我试图实际更改行上已确认 属性 的值。

这是该组件的示例代码。

import React, { useState, useEffect } from 'react'
import { Checkbox } from '@mui/material';
import { DataGrid } from '@mui/x-data-grid'

const DataTable = () => {

    const [tableData, setTableData] = useState([])

    function handleConfirmChange() {
      console.log('How do I change row state here????');
    }

    const columns = [
      { field: 'title', headerName: 'Title', width: 200 },
      { field: 'body', headerName: 'Body', width: 600 },
      {
        field: 'confirmed',
        headerName: 'Confirmed',
        renderCell: (params) => (
          <Checkbox
            checked={params.confirmed===1}
            onChange={handleConfirmChange}
          />
        ),
      }
    ]

    useEffect(() => {
        fetch("https://jsonplaceholder.typicode.com/posts")
          .then((data) => data.json())
          .then((data) => {
            for (var i=0; i<data.length; i++) {
              data[i].confirmed = false;
            }
            setTableData(data);
          })
    
      }, [])

  return (
    <div style={{ height: 700, width: '100%' }}>
      <DataGrid
        rows={tableData}
        columns={columns}
        pageSize={12}
      />
    </div>
  )
}

export default DataTable

checked={params.confirmed===1} 语句中,params 属性 中的 confirmed 不是 tableData 中的 属性。它是列的字段名称。

要获取点击的行,我们必须为每一行设置Id,将rowId作为checkbox的参数传递,然后我们可以识别点击的行。

因此,在 useEffect 钩子中,我们必须根据索引设置 rowId

useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/posts")
      .then((data) => data.json())
      .then((data) => {
        setTableData(
          data.map((x, index) => ({
            ...x,
            rowId: index,
            confirmed: false
          }))
        );
      });
  }, []);

然后在复选框单击事件中将 row 作为参数传递。另外,将 checked 属性 设置为 params.rows?.confirmedparams.rows 给出了实际的行数据。这些行在初始化期间可能为空,因此我们必须将 Optional chaining (?.) 设置为 confirmed 属性.

 <Checkbox
   checked={params.rows?.confirmed}
   onChange={() => handleConfirmChange(params.row)}
 />

handleConfirmChange函数中,获取点击的行并更新confirmed属性。遍历 tableData 数组并获取点击的行,然后设置 confirmed 并更新网格。

function handleConfirmChange(clickedRow) {
const updatedData = tableData.map((x) => {
  if (x.rowId === clickedRow.rowId) {
    return {
      ...x,
      confirmed: !clickedRow.confirmed
    };
  }
  return x;
});
setTableData(updatedData);

}

这是更新后的工作代码和codesandbox。

import React, { useState, useEffect } from "react";
import { Checkbox } from "@mui/material";
import { DataGrid } from "@mui/x-data-grid";

export default function DataTable() {
  const [tableData, setTableData] = useState([]);

  function handleConfirmChange(clickedRow) {
    const updatedData = tableData.map((x) => {
      if (x.rowId === clickedRow) {
        return {
          ...x,
          confirmed: true
        };
      }
      return x;
    });
    setTableData(updatedData);
  }

  const columns = [
    { field: "title", headerName: "Title", width: 200 },
    { field: "body", headerName: "Body", width: 400 },
    {
      field: "confirmed",
      headerName: "Confirmed",
      renderCell: (params) => (
        <Checkbox
          checked={params.rows?.confirmed}
          onChange={() => handleConfirmChange(params.row.rowId)}
        />
      )
    }
  ];

  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/posts")
      .then((data) => data.json())
      .then((data) => {
        setTableData(
          data.map((x, index) => ({
            ...x,
            rowId: index,
            confirmed: false
          }))
        );
      });
  }, []);

  return (
    <div style={{ height: 400, width: "100%" }}>
      <DataGrid
        rows={tableData}
        columns={columns}
        pageSize={12}
        rowsPerPageOptions={[12]}
      />
    </div>
  );
}