Source:  Twitter logo

I have a table inside a functional component. Each row in the table has an edit button at the end of the row. When I click an Edit button it applies the changes to all the edit buttons. How do I know which button is clicked and apply changes only to that? (I have a large number of rows so I cannot create a state for each button)

Here is a link to my code

One way you can do is keep track of row index on the state. For example, provide id to the button, which is equal to index of the row

 <Button id={index} type="button" onClick={e => this.handleEdit(e)}>

and in your handleEdit function

  handleEdit = e => {
    e.preventDefault();
    this.setState({
      showbutton: true,
      showButtonIndex: Number(e.target.id)
    });
  };

This way you have a index of the clicked row in the state and you can change your logic to show your <Edit /> component as

{this.state.showbutton && (this.state.showButtonIndex === index) && <Edit />}

I am assuming, you are allowing only one row to edit at a time.

Working code here

8 users liked answer #0dislike answer #08
Prakash Kandel profile pic
Prakash Kandel

I do not understand what the desired behavior of the button is, however, it seems that this is the relevant code for creating the buttons

  handleEdit = (e) => {
    e.preventDefault();
    this.setState({
      showbutton: true
    });
  };
  render() {
    console.log(this.state.names);
    return (
      <div>
        <h2> Names: </h2>
        <Table>
          <thead>
            <tr>
              <th>Name</th>
            </tr>
          </thead>
          {this.state.names.map((name, index) => {
            return (
              <tbody>
                <tr>
                  <td> {name} </td>
                  <td>
                    <Button type="button" onClick={e => this.handleEdit(e)}>
                      Edit
                    </Button>
                  </td>
                  {this.state.showbutton && <Edit />}
                </tr>
              </tbody>
            );
          })}
        </Table>
      </div>
    );
  }

You can see in the this.states.map() function that there is an index parameter that gets bound. You can use this to keep track of which button is calling the function and passing that into the function as such

handleEdit = (e, id) => {
    e.preventDefault();
    console.log(id);
    this.setState({
      showbutton: true
    });
  };
  render() {
    console.log(this.state.names);
    return (
      <div>
        <h2> Names: </h2>
        <Table>
          <thead>
            <tr>
              <th>Name</th>
            </tr>
          </thead>
          {this.state.names.map((name, index) => {
            return (
              <tbody>
                <tr>
                  <td> {name} </td>
                  <td>
                    <Button type="button" onClick={e => this.handleEdit(e, index)}>
                      Edit
                    </Button>
                  </td>
                  {this.state.showbutton && <Edit />}
                </tr>
              </tbody>
            );
          })}
        </Table>
      </div>
    );
  }

The example just prints the id of the button that clicked it. You can utilize this in whatever way necessary to uniquely identify the buttons.

The code is here

1 users liked answer #1dislike answer #11
Ben profile pic
Ben

I make some changes here

  1. Convert the state to an array of objects with showbutton in every id.
  2. Change the function to handle extra parameter id
1 users liked answer #2dislike answer #21
David profile pic
David

Copyright © 2022 QueryThreads

All content on Query Threads is licensed under the Creative Commons Attribution-ShareAlike 3.0 license (CC BY-SA 3.0).