trying to follow the React tutorial at the following link to CRUD data but can't find why my code getAction does not receive any 'id' because of that isInEditMode is not true so my button doesn't change to Save and Cancel
import React, { useEffect, useMemo, useState } from 'react';
import axios from 'axios';
import { Box, Typography,} from '@mui/material';
import Button from '@mui/material/Button';
import AddIcon from '@mui/icons-material/Add';
import EditIcon from '@mui/icons-material/Edit';
import DeleteIcon from '@mui/icons-material/DeleteOutlined';
import SaveIcon from '@mui/icons-material/Save';
import CancelIcon from '@mui/icons-material/Close';
import EditToolbar from './EditToolbar';
import {
GridRowModes,
DataGrid,
GridToolbarContainer,
GridActionsCellItem,
GridRowEditStopReasons,
} from '@mui/x-data-grid';
const AdminView = ()=> {
const [rows, setRows] = React.useState([]);
const [rowModesModel, setRowModesModel] = React.useState({});
useEffect(() => {
// Fetch user data from the database using Axios
axios.get('http://localhost:3001/users')
.then(response => {
setRows(response.data);
})
.catch(error => {
console.error('Error fetching user data:', error);
});
}, []);
const [columns, setColumns] = useState([
{ field: "id"},
{ field: "staff_number", editable: true },
{ field: "name", editable: true },
{ field: "surname", editable: true },
{ field: "email", editable: true },
{ field: "password", editable: true },
{ field: "access_level", editable: true },
{
field: 'actions',
type: 'actions',
headerName: 'Actions',
width: 100,
cellClassName: 'actions',
getActions: ({ id }) => {
console.log('get action:', rowModesModel[id]);
const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit;
if (isInEditMode) {
return [
<GridActionsCellItem
icon={<SaveIcon />}
label="Save"
sx={{
color: 'primary.main',
}}
onClick={handleSaveClick(id)}
/>,
<GridActionsCellItem
icon={<CancelIcon />}
label="Cancel"
className="textPrimary"
onClick={handleCancelClick(id)}
color="inherit"
/>,
];
}
return [
<GridActionsCellItem
icon={<EditIcon />}
label="Edit"
className="textPrimary"
onClick={handleEditClick(id)}
color="inherit"
/>,
<GridActionsCellItem
icon={<DeleteIcon />}
label="Delete"
onClick={handleDeleteClick(id)}
color="inherit"
/>,
];
},
}
]);
const handleEditClick = (id) => () => {
setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.Edit } });
};
const handleSaveClick = (id) => () => {
console.log('handleSaveClick:', id);
setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.View } });
};
const handleDeleteClick = (id) => () => {
setRows(rows.filter((row) => row.id !== id));
};
const handleCancelClick = (id) => () => {
setRowModesModel({
...rowModesModel,
[id]: { mode: GridRowModes.View, ignoreModifications: true },
});
const editedRow = rows.find((row) => row.id === id);
if (editedRow.isNew) {
setRows(rows.filter((row) => row.id !== id));
}
};
const handleModeRowsChange = (newRowModesModel ) => {
console.log('newRowModesModel change to:', newRowModesModel);
setRowModesModel(newRowModesModel);
}
const handleRowEditStop = (params, event) => {
console.log('handleRowEditStop params:', params);
if (params.reason === GridRowEditStopReasons.rowFocusOut) {
event.defaultMuiPrevented = true;
}
};
const processRowUpdate = (newRow) => {
console.log('processRowUpdate newRow returned:', newRow);
const updatedRow = { ...newRow, isNew: false };
setRows(rows.map((row) => (row.id === newRow.id ? updatedRow : row)));
console.log('updatedRow returned:', updatedRow);
return updatedRow;
};
return (
<div>
<DataGrid
rows={rows}
columns={columns}
editMode="row" // allow all row edit
checkboxSelection
rowModesModel={rowModesModel} // control modes of rows
onRowModesModelChange={handleModeRowsChange} // set the variable to control the row modes rowModesModel edit, view, add
onRowEditStop={handleRowEditStop} // stop the edit mode
processRowUpdate={processRowUpdate}
slots={{
toolbar: EditToolbar,
}}
slotProps={{
toolbar: { setRows, setRowModesModel },
}}
/>
</div>
);
};
export default AdminView;
my tooldbar button
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import AddIcon from '@mui/icons-material/Add';
import EditIcon from '@mui/icons-material/Edit';
import DeleteIcon from '@mui/icons-material/DeleteOutlined';
import SaveIcon from '@mui/icons-material/Save';
import CancelIcon from '@mui/icons-material/Close';
import {
GridRowModes,
DataGrid,
GridToolbarContainer,
GridActionsCellItem,
GridRowEditStopReasons,
} from '@mui/x-data-grid';
import {
randomCreatedDate,
randomTraderName,
randomId,
randomArrayItem,
} from '@mui/x-data-grid-generator';
function EditToolbar(props) {
const { setRows, setRowModesModel } = props;
const handleClick = () => {
// Generate a unique ID for the new row.
const id = randomId(); // Ensure `randomId` is a function that returns a unique ID.
// Add a new row at the end of the grid with empty fields.
setRows((oldRows) => [
...oldRows, // Keep all existing rows.
{
id, // Assign the new unique ID.
name: '', // Start with an empty name.
surname: '', // Start with an empty surname.
email: '', // Start with an empty email.
password: '', // Start with an empty password.
access_level: '', // Start with an empty access level.
staff_number: '', // Start with an empty staff number.
isNew: true // Flag this row as new for special handling like focusing.
}
]);
// Set the new row to be in edit mode, focusing on the 'staff_number' field.
setRowModesModel((oldModel) => ({
...oldModel, // Keep all existing row modes.
[id]: { mode: GridRowModes.Edit, fieldToFocus: 'staff_number' } // Set the new row to edit mode.
}));
};
return (
<GridToolbarContainer>
<Button color="primary" startIcon={<AddIcon />} onClick={handleClick}>
Add record
</Button>
</GridToolbarContainer>
);
}
export default EditToolbar;
Do not wrap columns into useState - just initiate them as regular const
const columns = [
{ field: "id"},
{ field: "staff_number", editable: true }
...
]