Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
607 views
in Technique[技术] by (71.8m points)

javascript - Material-UI DataGrid Component Refresh with new State Data

Good morning,

We are using Material-UI to create a DataGrid table filled with users and want to be able to delete selected entries (checkbox) using a button.

Clicking the button updates the state of our object (removing the expected rows) and the DataGrid element of Material-UI takes as parameter this.state.rows (as explained in this Stack Overflow).

The logs shown below prove that the state element is indeed updated following the setState() call (blue rectangle) which re-renders the DataGrid Component (red rectangle). However nothing changes visually :(

Console Log

The code is shown below:

import { DataGrid } from '@material-ui/data-grid';
import * as React from 'react';

import Button from '@material-ui/core/Button';
import { makeStyles } from '@material-ui/core/styles';
import DeleteIcon from '@material-ui/icons/Delete';

class EmployeeGrid extends React.Component {

    constructor(props) {
        super(props);
        this.handleDelete = this.handleDelete.bind(this);
        this.hrefs = {}
        this.columns = [
            { field: 'id', headerName: 'ID', width: 70 },
            { field: 'firstName', headerName: 'First name', width: 130 },
            { field: 'lastName', headerName: 'Last name', width: 130 },
            { field: 'description', headerName: 'Description', width: 200 }
        ];
        
        let employeeList = [];
        let id = 1;
        for (const employee of this.props.employees) {
            this.hrefs[id] = employee.url;
            employeeList.push({
                id: id,
                firstName: employee.entity.firstName,
                lastName: employee.entity.lastName,
                description: employee.entity.description
            });
            id++;
        }
        console.log(this.hrefs)
        console.log(employeeList)
        this.state={rows: employeeList, //populate initial state with all employees from database
                    selected: [],
                    nbRender: 1}
        console.log(this.state.rows);
    }

    handleDelete() {
        for (let id of this.state.selected) {
            this.state.rows.splice(id - 1, 1); //delete rows that were selected
            this.props.onDelete(this.hrefs[id]); //delete from database
        }
        this.setState({rows: this.state.rows, selected: [], nbRender: 2}, () => {
            console.log(this.state.rows) //checks state is indeed updated
        });
        console.log(this.state.rows);
    }

    render() {
        console.log("In render of EmployeeGrid");
        console.log(this.state.rows)
        return (
            <div>
                <div style={{ height: 400, width: '100%' }}>
                    <DataGrid rows={this.state.rows} //populate grid with state.rows
                                columns={this.columns}
                                pageSize={this.props.pageSize}
                                checkboxSelection 
                                onSelectionChange={(newSelection) => {
                                    this.setState({selected: newSelection.rowIds})
                                }}/>
                </div>
                <div>
                    <Button variant="contained"
                            color="secondary"
                            startIcon={<DeleteIcon />}
                            onClick={this.handleDelete}>
                                Delete
                    </Button>
                </div>
            </div>   
        )
    }
}

export default EmployeeGrid;

EDIT 1

After more analysis, we found that the reason why the log shows 4 rows in the console logs is because we updated the state inplace at line:

this.state.rows.splice(id - 1, 1); //delete rows that were selected

We now notice that the following line is never called which in turn does not re-render the page update.

 this.setState({rows: this.state.rows, selected: [], nbRender: 2}, () => {
            console.log(this.state.rows) //checks state is indeed updated
        });

Once again any ideas on why this could arise would be much appreciated!

Cheers and keep safe

question from:https://stackoverflow.com/questions/65883631/material-ui-datagrid-component-refresh-with-new-state-data

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Seems like you mutate state here

this.state.rows.splice(id - 1, 1)

Try this one

handleDelete() {
    for (let id of this.state.selected) {
        this.props.onDelete(this.hrefs[id]); //delete from database
    }
    this.setState((prevState) => ({
      ...prevState,
      rows: prevState.rows.filter((row) => !prevState.selected.includes(row.id)),
      selected: [], 
      nbRender: 2
    }));
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...