I am creating a material UI table based on a response from an API. the data has about 100 rows. For some of the columns, the table cells need to be text fields, that user can change on the go.
However, mapping over all the rows and creating text fields for some of the columns is making the table to load slower. I have attached the code for the table component, is there a way to optimize this?
const StyledTableCell = styled(TableCell)(({ theme }) => ({
[`&.${tableCellClasses.head}`]: {
backgroundColor: '#E10174',
color: theme.palette.common.white,
minWidth: '100px'
},
[`&.${tableCellClasses.body}`]: {
fontSize: 12,
},
}));
const StyledTableRow = styled(TableRow)(({ theme }) => ({
'&:nth-of-type(odd)': {
backgroundColor: theme.palette.action.hover,
},
// hide last border
'&:last-child td, &:last-child th': {
border: 0,
},
}));
export default function CustomizedTables(props) {
const {data, checked, handleChange, lockGroupOptions} = props
// The data prop is the data I am sending from the app component. It is an API response. the first object in the array may look like following
//{SKU: "xxxxxxxxxxxx", DetailDescription: "some description", Lockgroup: "some category", MaterialStandardName: "name", Notes: "some notes", StandardCost: 12, StatusName: "status", SubCategory: "some subcategory", 2023-05-08: 2 ,2023-05-15: 3, 2023-05-22: 4, 2023-05-29: 5, 2023-06-05: 6, 2023-06-12: null, 2023-06-19: null, 2023-06-26: null, 2023-07-03: null, 2023-07-10: null}
const [tableHeaderData, setTableHeaderData] = useState([])
const [tableBodyData, setTableBodyData] = useState([])
const [page, setPage] = React.useState(0);
const [rowsPerPage, setRowsPerPage] = React.useState(10);
// UseEffect is setting the states tableHeaderData and tableBodyData, which is used to create the header cells and body cells respectively
useEffect(() => {
if(data.list){
setTableHeaderData(prevTableHeaderData => Object.keys(data.list[0]))
setTableBodyData(prevTableBodyData => data.list)
}
}, [data.list])
const handleChangePage = (event, newPage) => {
setPage(newPage);
};
const handleChangeRowsPerPage = (event) => {
setRowsPerPage(parseInt(event.target.value, 10));
setPage(0);
};
const lockGroupMenuItems = lockGroupOptions.map(option => <MenuItem value={option}>{option}</MenuItem>)
const tableHeaderCells = tableHeaderData.map(headerCell =>
headerCell === 'Lockgroup'
?
<StyledTableCell align = 'center'>
<FormControl sx ={{minWidth: '150px'}} size="small">
<InputLabel sx = {{color: '#fff'}} id="demo-select-small-label">{headerCell}</InputLabel>
<Select sx ={{}}
labelId="demo-select-small-label"
id="demo-select-small"
value=''
name='{option}'
label="LockGroup"
onChange={() => console.log('hello')}
>
<MenuItem value="">
<em>None</em>
</MenuItem>
{lockGroupMenuItems}
</Select>
</FormControl>
</StyledTableCell>
:
<StyledTableCell align = 'center'>{headerCell}</StyledTableCell>
)
const tableBodyCells = (rowsPerPage > 0 ? tableBodyData.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) : tableBodyData).map(tableRow =>
<StyledTableRow key={tableRow.SKU} sx = {{cursor: 'pointer'}}>
<StyledTableCell align = 'center'><Checkbox size = 'small' name = {tableRow.SKU} checked = {checked.includes(tableRow.SKU) ? true : false} onChange = {handleChange} /></StyledTableCell>
{tableHeaderData.map(key => !key.includes('-')
?
<StyledTableCell align="center">{tableRow[key]}</StyledTableCell>
:
<StyledTableCell align = 'center'>
<TextField
size="small"
id="outlined-helperText"
label=''
value=''
onChange={() => console.log('clicked')}
defaultValue={tableRow[key]}
/>
</StyledTableCell>
)}
</StyledTableRow>)
return (
<ThemeProvider theme = {theme}>
<TableContainer component={Paper}>
<Table sx={{borderRadius: '5px'}} aria-label="customized table">
<TableHead sx = {{position: 'sticky', top: '0'}}>
<TableRow sx = {{cursor: 'pointer'}}>
<StyledTableCell sx = {{maxWidth: '200px', backgroundColor: 'black'}} align = 'center' >Select All</StyledTableCell>
{tableHeaderCells}
</TableRow>
</TableHead>
<TableBody>
{tableBodyCells}
</TableBody>
<TableFooter >
<TableRow >
<TablePagination
rowsPerPageOptions = {[5, 10, 25]}
component="div"
count={100}
page={page}
onPageChange={handleChangePage}
rowsPerPage={rowsPerPage}
onRowsPerPageChange={handleChangeRowsPerPage}
/>
</TableRow>
</TableFooter>
</Table>
</TableContainer>
</ThemeProvider>
);
}
Table pagination helps reduce the load time, but the actual requirement is to show all 100 rows in the page.
Any help would be great. Thanks!