如何删除 Material UI DataGrid (Reactjs) 中的特定行

Posted

技术标签:

【中文标题】如何删除 Material UI DataGrid (Reactjs) 中的特定行【英文标题】:How to delete a specific row in Material UI DataGrid (Reactjs) 【发布时间】:2021-01-21 18:04:04 【问题描述】:

我正在 react 中启动这个项目,目前进展顺利。 但是,我遇到了一个问题。

我想要的功能是这样的:我想要删除你看到的每一行,在该行的复选框被点击的位置。例如,如果我单击第 1 行和第 3 行中的复选框,我希望删除第 1 行和第 3 行。我还想跟踪我决定删除的行。

问题是我不知道该怎么做,即使做了研究,我仍然觉得如何解决这个问题。

目前我正在使用我在网上找到的一些示例 JSON 数据填充此表,所以不要介意存在的奇怪数据。此外,如果有人对实现这一目标的更简单或更清洁的方法提出建议,请随时在 cmets 中告诉我。

代码如下:

import React,  Component  from 'react';
import  DataGrid  from '@material-ui/data-grid';
import Button from '@material-ui/core/Button';


const columns = [
     field: 'id', headerName: 'ID', width: 70 ,
     field: 'firstName', headerName: 'First name', width: 130 ,
     field: 'lastName', headerName: 'Last name', width: 130 ,
    
      field: 'age',
      headerName: 'Age',
      type: 'number',
      width: 90,
    ,
    
      field: 'fullName',
      headerName: 'Full name',
      description: 'This column has a value getter and is not sortable.',
      sortable: false,
      width: 160,
      valueGetter: (params) =>
        `$params.getValue('firstName') || '' $params.getValue('lastName') || ''`,
    ,
     field: 'city', headerName: 'City', width: 100 ,
     field: 'state', headerName: 'State', width: 100 ,
  ];
  
  const rows = [
     id: 1, lastName: 'Snow', firstName: 'Jon', age: 35, city: 'Milwaukee', state: 'Wisconsin' ,
     id: 2, lastName: 'Lannister', firstName: 'Cersei', age: 42, city: 'Dubuque', state: 'Iowa' ,
     id: 3, lastName: 'Lannister', firstName: 'Jaime', age: 45, city: 'Appleton', state: 'Wisconsin',
     id: 4, lastName: 'Stark', firstName: 'Arya', age: 16, city: 'Madison', state: 'Wisconsin' ,
     id: 5, lastName: 'Targaryenmnsdlfbsjbgjksbgksbfksfgbk', firstName: 'Daenerys', age: null, city: 'Green Bay', state: 'Wisconsin' ,
     id: 6, lastName: 'Melisandre', firstName: null, age: 150, city: 'San Antonio', state: 'Texas' , 
     id: 7, lastName: 'Clifford', firstName: 'Ferrara', age: 44, city: 'Dallas', state: 'Texas' ,
     id: 8, lastName: 'Frances', firstName: 'Rossini', age: 36, city: '***lyn', state: 'New York' ,
     id: 9, lastName: 'Roxie', firstName: 'Harvey', age: 65, city: 'Toledo', state: 'Ohio' ,
     id: 10, lastName: 'Larry', firstName: 'King', age: 105, city: 'Chicago', state: 'Illiniois' ,
     id: 11, lastName: 'Snow', firstName: 'Jon', age: 35, city: 'Milwaukee', state: 'Wisconsin' ,
     id: 12, lastName: 'Lannister', firstName: 'Cersei', age: 42, city: 'Dubuque', state: 'Iowa' ,
     id: 13, lastName: 'Lannister', firstName: 'Jaime', age: 45, city: 'Appleton', state: 'Wisconsin',
     id: 14, lastName: 'Stark', firstName: 'Arya', age: 16, city: 'Madison', state: 'Wisconsin' ,
     id: 15, lastName: 'Targaryenmnsdlfbsjbgjksbgksbfksfgbk', firstName: 'Daenerys', age: null, city: 'Green Bay', state: 'Wisconsin' ,
     id: 16, lastName: 'Melisandre', firstName: null, age: 150, city: 'San Antonio', state: 'Texas' , 
     id: 17, lastName: 'Clifford', firstName: 'Ferrara', age: 44, city: 'Dallas', state: 'Texas' ,
     id: 18, lastName: 'Frances', firstName: 'Rossini', age: 36, city: '***lyn', state: 'New York' ,
     id: 19, lastName: 'Roxie', firstName: 'Harvey', age: 65, city: 'Toledo', state: 'Ohio' ,
     id: 20, lastName: 'Larry', firstName: 'King', age: 105, city: 'Chicago', state: 'Illiniois' ,
  ];

class ElgibleContracts extends Component 
    render()
        return (
            <div style=textAlign: "center">
                <h1 style=fontFamily: "Stone">Elgible Contracts</h1>
                <span className="horizontal-line" />
                <div className="centerDiv" style= height: 380, width: 950>
                    <DataGrid rows=rows columns=columns pageSize=10 checkboxSelection />
                </div>
                <br />
                <Button variant="contained" color="primary" onClick=this.getInfo >Purge</Button>
            </div>
        )
    


export default ElgibleContracts;

【问题讨论】:

【参考方案1】:

我为此创建了一个沙盒:https://codesandbox.io/s/heuristic-davinci-n3vrz?file=/src/App.js

我使用了函数式组件和钩子,因为这是当今的最佳实践。

   const [rows, setRows] = useState(data);
   const [deletedRows, setDeletedRows] = useState([]);

   const handleRowSelection = (e) => 
    setDeletedRows([...deletedRows, ...rows.filter((r) => r.id === e.data.id)]);
  ;

  const handlePurge = () => 
    setRows(
      rows.filter((r) => deletedRows.filter((sr) => sr.id === r.id).length < 1)
    );
  ;

  return (
    <div style= textAlign: "center" >
      <h1 style= fontFamily: "Stone" >Elgible Contracts</h1>
      <span className="horizontal-line" />
      <div className="centerDiv" style= height: 380, width: 950 >
        <DataGrid
          rows=rows
          columns=columns
          pageSize=10
          checkboxSelection
          onRowSelected=handleRowSelection
        />
      </div>
      <br />
      <Button variant="contained" color="primary" onClick=handlePurge>
        Purge
      </Button>

【讨论】:

这只是在单击复选框时将其删除,但我只想在单击清除按钮时删除行。有什么想法吗?也感谢到目前为止的帮助! 我已经为此更新了我的答案和沙箱!看看吧! 谢谢!!!快速提问,将来我有一个历史页面,将向用户显示他们删除的内容的历史。我的问题是 - 要在我的历史组件中访问此组件中的 deleteditems 数组,我是否只需导入此组件并调用 deleteditems 来获取已删除的项目?谢谢! 那行不通。如果需要在不同组件之间使用deletedItems。你有两个选择,要么提升状态 (reactjs.org/docs/lifting-state-up.html),要么使用像 Redux (redux.js.org/basics/usage-with-react) 或 Mobx 这样的状态管理器。如果您需要对此进行演示,我很乐意这样做。 嘿@coder_coder123。我更新了沙箱以或多或少地显示它应该是怎样的。我采取了第一种方法,提升了状态。【参考方案2】:
const ElgibleContracts = () => 
  const [items, setItems] = React.useState(rows)
  const [selection, setSelection] = React.useState([]);
  const [deleted, setDeleted] = React.useState([])
  const handlePurge = () => 
    setDeleted([...deleted, ...selection])
    setItems(items.filter(i=> !selection.some(s=> s.id === i.id)))
    setSelection([])
  
  console.log("Here are deleted items",deleted)
        return (
            <div style=textAlign: "center">
                <h1 style=fontFamily: "Stone">Elgible Contracts</h1>
                <span className="horizontal-line" />
                <div className="centerDiv" style= height: 380, width: 950>
                    <DataGrid  onSelectionChange=(newSelection) => 
          setSelection(newSelection.rows);
         rows=items columns=columns pageSize=10 checkboxSelection />
                </div>
                <br />
                <Button variant="contained" color="primary" onClick=handlePurge >Purge</Button>
            </div>
        )
    

【讨论】:

这对我来说甚至都不会运行。不知道是语法还是逻辑问题 没关系,我犯了一个愚蠢的错误。它工作正常 - 谢谢!大声笑【参考方案3】:

onRowSelected 的使用很快就会出错,因为在取消选择 DataGrid 中的项目时必须重置 deletedRows。这就是为什么我建议使用onSelectionModelChange

const [rows, setRows] = useState(data);
const [deletedRows, setDeletedRows] = useState([]);

<DataGrid
  checkboxSelection
  columns=columns
  pageSize=5
  onSelectionModelChange=(selectionModel) => 
    const rowIds = selectionModel.map(rowId => parseInt(String(rowId), 10));
    const rowsToDelete = rows.filter(row => rowIds.includes(row.id));
    setDeletedRows(rowsToDelete);
  
  rows=rows
/>

【讨论】:

以上是关于如何删除 Material UI DataGrid (Reactjs) 中的特定行的主要内容,如果未能解决你的问题,请参考以下文章

Material-UI DataGrid:从状态中删除一行导致无法读取属性错误

如何以编程方式对 Material UI DataGrid 列进行排序?

如何使用 Material-UI DataGrid 保存列状态?

单击行材料-ui DataGrid内的按钮时如何设置行数据?

material UI datagrid 垂直滚动条

Material UI dataGrid 性能