How to dynamically update MaterialUI DataGrid table in React JS
The issue here is that you are not keeping the state of your data. I see you've attempted to use hooks - these will not work inside a class component so just use the state class property
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
};
Inside your handlePurge
method, this is where you set the new state for the filtered data
let data_to_be_kept = this.state.data.filter(function (item) {
return rowsToBeDeleted.includes(item.id) === false;
});
this.setState({
data: data_to_be_kept
});
Finally, in your DataGrid
, the value of prop
rows
should be assigned the value of the state
data
<DataGrid
rows={this.state.data}
columns={columns}
pageSize={10}
checkboxSelection
onRowSelected={this.handleRowSelection}
/>
coder_coder123
Updated on July 25, 2022Comments
-
coder_coder123 almost 2 years
here's the general synopsis of what I'm trying to do:
- When the user clicks a checkbox in a row, that row is saved from being deleted (typically the user will click more than row).
- Every record without a checked checkbox is deleted once the user hits "purge records" button.
I got some general advice on how to do it, and I used the advice I was given accompanied by my own logic to come up with an implementation. The issue is that although I think my logic looks good and all my console.log statements looks good, the data in the isn't updating. BTW, this is in a JSX file & not just a plain JS file.
I've been stuck on this for like a day now, and I'm genuinely stuck as to what my problem is/why this isn't working. Thank you for all your help and suggestions
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;
-
Oron Bendavid over 3 yearsI'm getting same error with hooks. Do you have any idea if it support it?
-
95faf8e76605e973 over 3 yearsregardless of class or function (i.e., hooks) it should work. to answer your question, yes - MUI DataGrid supports hooks. the general idea of how to solve this is to simply have the prop
rows
to have a dynamic value which is bound to astate
. when the state updates, theDataGrid
updates -
Oron Bendavid over 3 yearsThanks. I created simple example with useState for rows, but I'm facing super slow performance and data rendring. Currently I try to understand if it is related to a mismatch versions with react or react-dom
-
95faf8e76605e973 over 3 yearsif you are dealing with big data, i suggest you look into virtualized tables. here is an example from mui docs: material-ui.com/components/tables/#virtualized-table
-
Oron Bendavid over 3 yearsThanks for the info, my example uses small data, I fixed the issue by updating packages to "@material-ui/data-grid": "4.0.0-alpha.10", "@material-ui/core": "4.11.1", "react": "^17.0.1".
-
hfontanez over 2 yearsIs the logic backwards? Shouldn't "purge" function delete the selected rows? It is actually keeping the selected.