3

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
  • please add code here, instead of linking to it. Commented Mar 1, 2020 at 13:31
  • I would if I can.. It has 2 files.. It will be messy Commented Mar 1, 2020 at 13:35
  • Yes, but the problem is in deleteHandler function. Commented Mar 1, 2020 at 13:40
  • Refer this guide, vegibit.com/how-to-delete-an-item-from-an-array-in-react Commented Mar 1, 2020 at 13:52

4 Answers 4

6

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

Sign up to request clarification or add additional context in comments.

1 Comment

Hey man, I guess you forgot to add props.listofapi as a Effect dependencies. it doesn't work without.
1

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

Comments

1

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;

Comments

1

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.

1 Comment

Actually no, not necessarily. You still can edit the array that passed from props (see my sandbox link) but its not recommend unless you need to.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.