Reputation: 121
I am using a Material-UI table to render data retrieved from an API>. There is a form to add new entries but when this adds to the data the table is not updating/re-rendering and I can't figure out why.
This is edited for brevity/clarity...
const [data, setData] = useState();
useEffect(() => {
const fetchSummary = async () => {
setLoading(true);
const response = await axios
.get<TSalesSummary[]>(`/sales/${$reporterId}`, {})
.then((result) => {
setData(result.data);
})
.catch((error) => {
console.error('Retrieve Request Failed');
setError(error);
})
.finally(() => {
setLoading(false);
})
}
if (!data) {
fetchSummary();
}
}, [reporterId]);
const onSubmit = async (values: any, actions: any) => {
const result = await axios
.post<TSalesSummary>(`/sales/` + props.identifier + '/invite', {
first_name: values.firstName,
last_name: values.lastName,
email: values.email
})
.then((result ) => {
data?.unshift(result.data);
setData(data);
setPage(0);
})
.catch((error) => {
});
}
Component:
<TableContainer component={Paper}>
<Table sx={{minWidth: 650}} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell sx={{fontWeight: 700}}>
First Name
</TableCell>
<TableCell align="left" sx={{fontWeight: 700}}>
Last Name
</TableCell>
<TableCell align="left" sx={{fontWeight: 700}}>
Email
</TableCell>
<TableCell align="left" sx={{fontWeight: 700}}>
Status
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{(data
? data.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
: data
).map((row) => (
<TableRow
key={row.identifier}
sx={{
'&:last-child td, &:last-child th': {border: 0},
}}
>
<TableCell component="th" scope="row">{ row.first_name }</TableCell>
<TableCell align="left">{ row.last_name }</TableCell>
<TableCell align="left">{ row.email }</TableCell>
</TableRow>
))}
{data.length === 0 &&
<TableRow>
<TableCell rowSpan={3}>No records found</TableCell>
</TableRow>
}
</TableBody>
<TableFooter>
<TableRow>
<TablePagination
rowsPerPageOptions={[5, 10, 25, { label: 'All', value: -1 }]}
colSpan={3}
count={data.length}
rowsPerPage={rowsPerPage}
page={page}
SelectProps={{
inputProps: {
'aria-label': 'rows per page',
},
native: true,
}}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
/>
</TableRow>
</TableFooter>
</Table>
</TableContainer>
When onSubmit runs the data is updated (I can see in the console) but the table does not re-render. What do I need to do to make the table also update?
Upvotes: 1
Views: 4645
Reputation: 4873
Inside the onSubmit
handler, you are mutating the state variable data
and try to update the mutated data
.
data?.unshift(result.data);
setData(data);
It won't work because to react, the array object doesn't change (the reference to the array stay the same). The correct way to update a state variable is by setting it to a new data
array.
const newData = [...result.data, ...data];
setData(newData);
According to the React docs,
Never mutate state directly, as calling setState() afterwards may replace the mutation you made. Treat state as if it were immutable.
Upvotes: 3