如何在React JS中动态更新MaterialUI DataGrid表

时间:2020-10-08 19:20:59

标签: javascript reactjs react-native material-ui

这是我要执行的操作的简要提要:

  • 当用户单击行中的复选框时,该行将被保存,不会被删除(通常,用户单击多于该行)。
  • 用户点击“清除记录”按钮后,所有未选中复选框的记录都会被删除。

我获得了一些有关如何执行此操作的一般建议,并且我根据自己的逻辑给出了建议,以提出实现方案。问题是,尽管我认为我的逻辑看起来不错,并且所有console.log语句看起来都很不错,但是其中的数据没有更新。顺便说一句,它在一个JSX文件中,而不仅仅是一个普通的JS文件。

我已经在这上面停留了一天,而我真正的困扰是我的问题是什么/为什么这不起作用。谢谢您的所有帮助和建议


import React, { Component, useState } from "react";
import { DataGrid } from "@material-ui/data-grid";
import Button from "@material-ui/core/Button";
import DeleteIcon from '@material-ui/icons/Delete';
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 }
];

var data = [
  {
    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: "Brooklyn",
    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: "Brooklyn",
    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"
  }
];

var rowsToKeep = [];
var rowsToBeDeleted = [];

class ElgibleContracts extends Component {
  //const [rows, setRows] = useState(data);
  //const [deletedRows, setDeletedRows] = useState([]);

  /*
  * It's assumed that the user will want to delete all the rows,
  * but there will be scenarios when that's not the case.
  */
  setRowsToBeDeleted = () => {
    for (var i = 0; i < data.length; i++){
      rowsToBeDeleted.push(data[i].id);
    }
    rowsToBeDeleted = [...new Set(rowsToBeDeleted)]; //Did this because clicking the button twice will make doubles appear for each row
    
  };

  /*
   * This method fires off when the checkbox is clicked for a given row.
  */
  handleRowSelection = (e) => {
    // remove it if it's already present - this means the user unchecked it
    if (rowsToKeep.includes(e.data.id)){
      for(var i = 0; i < rowsToKeep.length; i++){ 
        if (rowsToKeep[i] === e.data.id){ 
          rowsToKeep.splice(i, 1); 
        }
      }
    } else {
      // user clicked it - add it to the list of rows to keep.
      rowsToKeep.push(e.data.id);
    }

    this.setRowsToBeDeleted();
    console.log("Rows to Keep: " + rowsToKeep);
    //setDeletedRows([...deletedRows, ...rows.filter((r) => r.id === e.data.id)]);
    //console.log("All rows: " + rows);
  };

  /*
  * This method updates the data that's to be displayed.
  */
  handlePurge = () => {
    // Check to see what rows are to be deleted and which ones aren't.
    for (var j = 0; j < rowsToKeep.length; j++){
      if (rowsToBeDeleted.includes(rowsToKeep[j])){
        // delete it from 'rows to be deleted' array
        console.log("Found:" + rowsToKeep[j]);
        while(rowsToBeDeleted.indexOf(rowsToKeep[j]) !== -1) {
          rowsToBeDeleted.splice(rowsToBeDeleted.indexOf(rowsToKeep[j]), 1)
        }
      } else {
        // do nothing
      }
    } 

    // remove it from the data set. Just used ID of 1 in this case to test whether or not it would work
    data = data.filter(function(item) { 
      return item.id !== 1;  
    });
    
    console.log("Rows to Delete: " + rowsToBeDeleted);
    console.log("Here are deleted items",rowsToBeDeleted);
  };

  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={data}
          columns={columns}
          pageSize={10}
          checkboxSelection
          onRowSelected={this.handleRowSelection}
        />
      </div>
      <br />
      <Button variant="contained" color="primary" startIcon={<DeleteIcon />} style={{textTransform: "none"}} onClick={this.handlePurge}>
        Purge Records
      </Button>
    </div>
  );
};
}

export default ElgibleContracts;

enter image description here

1 个答案:

答案 0 :(得分:0)

这里的问题是您没有保留数据的状态。我看到您已经尝试使用钩子-这些钩子在类组件内部不起作用,因此只需使用状态类属性

class ElgibleContracts extends Component {
  //const [rows, setRows] = useState(data); <-- this will not work in class component
  //const [deletedRows, setDeletedRows] = useState([]); <-- this will not work in class component

  state = {
    data: data // use state class property instead
  };

在您的handlePurge方法中,您可以在此处为过滤后的数据设置新状态

let data_to_be_kept = this.state.data.filter(function (item) {
  return rowsToBeDeleted.includes(item.id) === false;
});

this.setState({
  data: data_to_be_kept
});

最后,在您的DataGrid中,应该为prop rows的值分配state data

<DataGrid
  rows={this.state.data}
  columns={columns}
  pageSize={10}
  checkboxSelection
  onRowSelected={this.handleRowSelection}
/>

Edit hopeful-bouman-6s9mo