2

I'm trying to figure out how to remove a row from a simple table using a simple button.

I try to use the index but with what I wrote, when I click on the line to delete, it is only all the others that are deleted ...

I guess the problem comes from the way I use the index but I have some difficulties to understand the behavior.

 let users = [
        { firstName: "John", lastName: "Connor", age: 20 },
        { firstName: "Geralt", lastName: "Rivia", age: 45 },
        { firstName: "Nathan", lastName: "Drake", age: 36 }
    ]
    
    
    class exercice extends React.Component {
        constructor(props){
            super(props);
            this.state = {
                users: users
            }
        }
        
        onClickDeleteRow = index => {
            users = users.splice(index,1)
            this.setState({users: users})
            console.log(this.state.users)
        }
        
    
        render() {
            let usersName = this.state.users.map((user, index) => (
                <tr key={index}>
                    <td>{user.firstName} </td>
                    <td>{user.lastName} </td>
                    <td><button onClick={() => this.onClickDeleteRow(index)}>Delete</button></td>
                </tr>
            ))
    
            return (
                <table>
                    <thead>
                        <tr>
                            <th> firstName </th>
                            <th> lastName</th>
                        </tr>
                    </thead>
                    <tbody>
                        {usersName}
                    </tbody>
                </table>
            )
        }
    }
    
    ReactDOM.render(
        <div className="firstContainer">
            <Exercice />
        </div>,
        document.getElementById('root')
    
    )

2 Answers 2

2

.splice() method returns an array containing the elements that were removed from the original array on which .splice() method was called. So if index is 1, then

users = users.splice(index,1)

will update users and assign an array containing one element to the users constant. If index is 1 then after the above statement, users will be

users = [{ firstName: "Geralt", lastName: "Rivia", age: 45 }]

which is what gets set in the state. That is why all other rows are removed except the one that you wanted to delete.

Solution

You could solve the problem in couple of ways:

  1. Change

    users = users.splice(index, 1);
    

    to

    users.splice(index, 1);
    

    this will make sure that you don't update the users with the return value of .splice() method.

  2. Problem with the first approach is that it modifies the original users array. You could avoid modifying the users array by using the .filter() method.

    Change the onClickDeleteRow method as shown below:

    onClickDeleteRow = (index) => {
       const updatedUsers = this.state.users.filter((user, idx) => idx !== index);
       this.setState({ users: updatedUsers });
    };
    
Sign up to request clarification or add additional context in comments.

4 Comments

Nice answer - very well explained.
Thank you very much for this great explanation, it helped me a lot! Everything is working fine. I have another little question related to calling onClickDeleteRow in the render. I still have a little trouble understanding why onClick = {() => this.onClickDeleteRow (index)} is correct but not just this.onClickDeleteRow (index).
Value of the onClick prop should be a function, so when you do onClick={this.onClickDeleteRow (index)}, you are not passing a function, you are calling the onClickDeleteRow function and setting its return value as a value of the onClick prop. onClick prop needs a function that React can call in response to a click.
Ok, so it explains this error Cannot update during an existing state transition (such as within render). Render methods should be a pure function of props and state. Thanks for taking a little of your time to help me, that's really nice of you.
0

I think you should call this.state.users in the method

  onClickDeleteRow = index => {
        const users = this.state.users;
        users.splice(index, 1);
        this.setState({ users: users });  
      };

Comments

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.