Rob Irvin
Rob Irvin

Reputation: 121

Material UI Table not Updating when new records added

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

Answers (1)

hangindev.com
hangindev.com

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

Related Questions