mui / mui-x

MUI X: Build complex and data-rich applications using a growing list of advanced React components, like the Data Grid, Date and Time Pickers, Charts, and more!
https://mui.com/x/
4.04k stars 1.25k forks source link

Deleting rows does not reset selected row information #14251

Closed RotateAt60MPH closed 3 weeks ago

RotateAt60MPH commented 3 weeks ago

Steps to reproduce

Link to live example: (required)

Steps:

  1. add the below react function component to a react, material-ui project
  2. select a row from the data grid
  3. click the delete button

Current behavior

When delete is clicked, the selected row is deleted from React state, but the selected row count text does not reset and is not possible to reset, even with a forceUpdate(). Selected indexes are not cleared out.

import { DataGrid, useGridApiRef } from "@mui/x-data-grid";
import Button from "@mui/material/Button";
import { useState } from "react";

// Data

const userTableLayout = {
  columns: [
    { field: 'id', headerName: 'User Id', width: 90, editable: false },
    {
      field: 'userName',
      headerName: 'User Name',
      flex: 1, editable: false
    },
    {
      field: 'nickName',
      headerName: 'Full Name',
      flex: 1, editable: false
    }
  ],

  rows: [ 
    {id: 1, userName: "userName1", nickName: "nickName1"},
    {id: 2, userName: "userName2", nickName: "nickName2"},
    {id: 3, userName: "userName3", nickName: "nickName3"},
   ],
};

export const UserPage = () => {
  const [selection, setSelection] = useState([]);
  const [tableData, setTableData] = useState(userTableLayout);
  const apiRef = useGridApiRef();

  const onDeleteClicked = () => {
    const newRows = tableData.rows.filter(
      (user) => !selection.includes(user.id)
    );
    const newTableData = {
      ...tableData,
      rows: newRows,
    };

    setTableData(newTableData);
    apiRef.current.forceUpdate();
  };

  return (
    <>
      <DataGrid
        apiRef={apiRef}
        keepNonExistentRowsSelected
        rows={tableData.rows}
        columns={tableData.columns}
        onRowSelectionModelChange={setSelection}
        initialState={{
          pagination: {
            paginationModel: {
              pageSize: 15,
            },
          },
        }}
        pageSizeOptions={[5, 10, 15, 20]}
        checkboxSelection
        disableRowSelectionOnClick
        rowHeight={30}
        columnHeaderHeight={30}
        autoHeight
      />
      {selection.length > 0 && (
        <Button
          onClick={onDeleteClicked}
          color="secondary"
          variant="contained"
          size="small"
        >
          Delete
        </Button>
      )};
    </>
  );
};

Expected behavior

The selected rows state of the DataGrid should reset.

Context

Need to be able to delete rows and have the selected rows reset.

Your environment

npx @mui/envinfo ``` Fixfox 129.0.1 System: OS: Windows 10 10.0.19045 Binaries: Node: 16.17.0 - C:\Program Files\nodejs\node.EXE npm: 10.8.2 - ~\AppData\Roaming\npm\npm.CMD pnpm: Not Found Browsers: Chrome: Not Found Edge: Chromium (127.0.2651.86) npmPackages: @emotion/react: ^11.13.0 => 11.13.0 @emotion/styled: ^11.13.0 => 11.13.0 @mui/core-downloads-tracker: 5.16.7 @mui/icons-material: 5.16.7 => 5.16.7 @mui/material: ^5.16.7 => 5.16.7 @mui/private-theming: 5.16.6 @mui/styled-engine: 5.16.6 @mui/system: 5.16.7 @mui/types: 7.2.15 @mui/utils: 5.16.6 @mui/x-data-grid: ^7.13.0 => 7.13.0 @mui/x-internals: 7.13.0 @types/react: ^18.3.3 => 18.3.3 react: ^18.3.1 => 18.3.1 react-dom: ^18.3.1 => 18.3.1 styled-components: ^6.1.12 => 6.1.12 ```

Search keywords: rows deletion selection

cravindra commented 3 weeks ago

Played around with the provided example and this may not be a bug with the DataGrid.

Could this be happening because keepNonExistentRowsSelected is set to true?

From the docs:

If true, the selection model will retain selected rows that do not exist. Useful when using server side pagination and row selections need to be retained when changing pages.

Also noticed that the code shared does not pass in selection back to the data grid as rowSelectionModel (but that is probably not the reason the reported error is happening).

Here is a minimal reproduction of the intended behaviour - hope it helps:


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

const initialRows = [
  { id: 1, userName: 'userName1', nickName: 'nickName1' },
  { id: 2, userName: 'userName2', nickName: 'nickName2' },
  { id: 3, userName: 'userName3', nickName: 'nickName3' },
];

const cols = [
  { field: 'id', headerName: 'User Id', width: 90, editable: false },
  {
    field: 'userName',
    headerName: 'User Name',
    flex: 1,
    editable: false,
  },
  {
    field: 'nickName',
    headerName: 'Full Name',
    flex: 1,
    editable: false,
  },
];
export default function Test() {
  const [rowSelectionModel, setRowSelectionModel] = React.useState([]);
  const [rows, setRows] = useState(initialRows);

  const handleDeleteSelected = () => {
    setRows((prev) => prev.filter((row) => !rowSelectionModel.includes(row.id)));
  };

  return (
    <div>
      <div style={{ height: 300, width: '100%' }}>
        <DataGrid
          rows={rows}
          columns={cols}
          checkboxSelection
          rowSelectionModel={rowSelectionModel}
          onRowSelectionModelChange={(newSelection) => {
            // This gets called with an empty array when the rows are updated after delete
            console.log('newSelection', newSelection);
            setRowSelectionModel(newSelection);
          }}
          slots={{ toolbar: GridToolbar }}
        />
      </div>
      {!!rowSelectionModel.length && (
        <Button onClick={handleDeleteSelected}>Delete Selected</Button>
      )}
    </div>
  );
}
RotateAt60MPH commented 3 weeks ago

That was exactly it. I had to remove 'keepNonExistentRowsSelected'. Not sure why I added it there in the first place, but removing it did the trick. And thanks also for the selection model suggestion.

github-actions[bot] commented 3 weeks ago

:warning: This issue has been closed. If you have a similar problem but not exactly the same, please open a new issue. Now, if you have additional information related to this issue or things that could help future readers, feel free to leave a comment.

@RotateAt60MPH: How did we do? Your experience with our support team matters to us. If you have a moment, please share your thoughts in this short Support Satisfaction survey.