React component doesn't re-render after delete row

Hello people! As I mentioned, I have a component which (I don’t know why) doesn’t rerender after I send a delete request. This is the component (sorry, I had to drop it all). The delete button sends a DELETE request to the server; that part works, (I get back a 200 and item gets successfully deleted from the db).
What doesn’t work is that it does not re-render afterwards.

import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableContainer from "@material-ui/core/TableContainer";
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";
import Paper from "@material-ui/core/Paper";

import {
  StyledTableCell,
  StyledTableRow,
  useCustomStyles,
} from "../../shared/useStyles";

import BookItemComponent from "../BookItemComponent";
import { useDispatch, useSelector } from "react-redux";
import { Fragment, useCallback, useEffect } from "react";
import { fetchInventary, removeItem } from "../../rtk/slices/inventary.slice";

import Add from "../pages/forms/addItem";
import Edit from "../pages/forms/editItem";
import Delete from "../utils/buttons/delete";
import { useHistory } from "react-router";

const InventoryTable = ({ onlyAvailable, type }) => {
  const classes = useCustomStyles();

  const dispatch = useDispatch();

  const inventary = useSelector((state) => state.inventary);
  const items = onlyAvailable
    ? inventary.filter((item) => item.isAvailable)
    : inventary;
  const initFetch = useCallback(() => {
    dispatch(fetchInventary());
  }, [dispatch]);

  useEffect(() => {
    initFetch();
  }, [initFetch]);

  const history = useHistory();

  const handleDelete = (id) => {
    alert(`This will delete the item with ID ${id} from the database`);
    dispatch(removeItem(id)).then((res) => history.push("/inventario"));
  };

  return (
    <Fragment>
      {type === "manage" ? <Add /> : null}
      <TableContainer component={Paper}>
        <Table className={classes.table} aria-label="last rents">
          <TableHead>
            <TableRow>
              <StyledTableCell className={classes.rowItemId}>
                I.D.
              </StyledTableCell>
              <StyledTableCell align="center">Modello</StyledTableCell>
              <StyledTableCell align="center">Oggetto</StyledTableCell>
              <StyledTableCell align="center">Disponibile</StyledTableCell>
              <StyledTableCell align="center">Quantità</StyledTableCell>
              <StyledTableCell></StyledTableCell>
              {type === "manage" ? <StyledTableCell></StyledTableCell> : null}
            </TableRow>
          </TableHead>
          <TableBody>
            {items.map((row) => (
              <StyledTableRow key={row.id}>
                <StyledTableCell
                  component="th"
                  scope="row"
                  className={classes.rowItemId}
                >
                  {row.id}
                </StyledTableCell>
                <StyledTableCell align="center">
                  {row.description}
                </StyledTableCell>
                <StyledTableCell align="center">{row.name}</StyledTableCell>
                <StyledTableCell align="center">
                  {row.isAvailable ? "Sì" : "No"}
                </StyledTableCell>
                <StyledTableCell align="center">
                  {row.quantity !== "" ? parseInt(row.quantity, 10) : ""}
                </StyledTableCell>
                {type === "rental" ? ( // if type is rental render the item and modal to book an item
                  <StyledTableCell align="center">
                    <BookItemComponent
                      isAvailable={row.isAvailable}
                      item={
                        <div>
                          {row.name}, <em>{row.description}</em>
                        </div>
                      }
                    />
                  </StyledTableCell>
                ) : (
                  // if type is not rental, render the buttons to edit and delete
                  <Fragment>
                    <StyledTableCell align="center">
                      <Edit rowId={row.id} description={row.description} />
                    </StyledTableCell>
                    <StyledTableCell align="center">
                      <Delete handleDelete={handleDelete} rowId={row.id} />
                    </StyledTableCell>
                  </Fragment>
                )}
              </StyledTableRow>
            ))}
          </TableBody>
        </Table>
      </TableContainer>
    </Fragment>
  );
};

export default InventoryTable;

This is the slice (if needed):

import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import InventaryService from "../../services/inventary.service";

export const fetchInventary = createAsyncThunk(
  "inventary/fetchInventary",
  async () => {
    const res = await InventaryService.getAll();
    return res.data;
  }
);

export const createItem = createAsyncThunk(
  "inventary/createItem",
  async (data) => {
    const res = await InventaryService.create(data);
    return res.data;
  }
);

export const removeItem = createAsyncThunk(
  "inventary/removeItem",
  async (id) => {
    const res = await InventaryService.removeOne(id);
    return res.data;
  }
);

const inventarySlice = createSlice({
  name: "inventary",
  initialState: [],
  reducers: {
    addItem(state, action) {
      state.unshift(action.payload);
    },
    deleteItem(state, action) {
      return state.filter((item) => item.id !== action.payload);
    },
  },
  extraReducers: {
    [fetchInventary.fulfilled]: (state, action) => {
      return [...action.payload];
    },
    [createItem.fulfilled]: (state, action) => {
      state.push(action.payload);
    },
    [removeItem.fulfilled]: (state, action) => {
      let index = state.findIndex(({ id }) => id === action.payload.id);
      state.splice(index, 1);
    },
  },
});

export const { addItem, deleteItem } = inventarySlice.actions;
export default inventarySlice.reducer;

My first idea is that since the component reads a copy of the state and not the state itself, it doesn’t realize that the state changed, but I still don’t really know how to fix this issue, since I need to conditionally render something or not based on a condition. Can someone please tell me how to fix this?

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.