Delete an Item from Array not Rendering ReactJS Hooks

Viewed 1563

I am trying to delete an item from Array using the Index, I am Passing the Props from Parent to Child Component to perform this operation, now i can see the console log that it's getting deleted, but it's not rendering the component

I have Posted the code in SandBox, since it will get messy here

Link : https://codesandbox.io/s/jovial-burnell-qkl7r

4 Answers

You are rendering data from props.listofapi but updating array, your changes don't get updated because you are changing the wrong array. .splice() removes/adds an item to/from array, you don't have to do setArray(...array, temp); but setArray(tempArray);

use useEffect to save the initial data to array.

const deleteHandler = id => {
  console.log(id);
  const tempArray = [...array];
  // removes item from tempArray
  tempArray.splice(id, 1); 
  setArray(tempArray);
  console.log("temp array", tempArray);
};

React.useEffect(() => {
  // data from props to array here
  setArray(props.listofapi);
}, [props.listofapi]);

and map array instead of props.listofapi

<TableBody>
      {array.map((row, index) => (
      ...

Example

The component only re-renders if there are state changes, what you actually doing is passing the props from parent to child, which are not state values. Hence you can try this following way where we need to set the local state first, so that when the state gets updated , the component will be re-renderd.

Just update the code with the following things

  React.useEffect(() =>{
    setArray(props.listofapi)
    //this acts as componentdidmount

  },[]);

  React.useEffect(() =>{
    console.log('state value changed', array)
    // this is the way a call back function is called in the hooks
  },[array]);

I have update the snippet

in your RenderList component, you need to set the state as the props that are being passed

const RenderList = props => {
  // console.log(props.listofapi);
  const classes = useStyles();


  const [array, setArray] = React.useState(props.listofapi); // to update the component

  const deleteHandler = index=> {
    console.log(id);
    setArray(array.filter((item, i) => i!== index));
  };

  return (
    <TableContainer
      component={Paper}
      className={classes.table}
      style={{ align: "center" }}
    >
      <Table
        stickyHeader
        className={classes.container}
        size="small"
        aria-label="a dense table"
      >
        <TableHead>
          <TableRow>
            <TableCell>User ID</TableCell>
            <TableCell>Name</TableCell>
            <TableCell>Use Name</TableCell>
            <TableCell>Email ID</TableCell>
            <TableCell>Edit </TableCell>
            <TableCell>Delete</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {array.map((row, index) => (
            <TableRow key={index}>
              <TableCell component="th" scope="row">
                {row.id}
              </TableCell>
              <TableCell>{row.name}</TableCell>
              <TableCell>{row.username}</TableCell>
              <TableCell>{row.email}</TableCell>
              <TableCell>
                <Button variant="contained" size="small" color="primary">
                  Edit Me
                </Button>
              </TableCell>
              <TableCell>
                <Button
                  variant="contained"
                  size="small"
                  color="primary"
                  onClick={() => deleteHandler(index)}
                >
                  Delete Me
                </Button>
              </TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>
    </TableContainer>
  );
};
export default RenderList;

Your problem you just misused spared. Try this:

  const deleteHandler = id => {
    // do your logic on the array that coming from props
    let temp = props.listofapi.splice(id, 1);
    // using spread
    setArray([...array, temp]);
  };

See your Code at codeSandbox

Edit: Please note that you are editing/deleting and mapping directly over the props.listofapi array and so, the .splice() method will change/remove its existing elements. If you don't want that, you should try @Junius L. solution.

Related