user8306074
user8306074

Reputation: 395

How to know which button is clicked when there are multiple buttons (React)

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

Upvotes: 1

Views: 12692

Answers (4)

Ryze
Ryze

Reputation: 1

function Lists() {
    const handleClick = (button) => {
        console.log(button.target);
    };

    return (
        <section className={css.actionList}>
            <div className={css.itemActive} onClick={handleClick}>
                Posts
            </div>
            <div className={css.itemActive} onClick={handleClick}>
                Comments
            </div>
            <div className={css.itemActive} onClick={handleClick}>
                Liked Posts
            </div>
        </section>
    );
}

I assume that you won't use props and pass to children elements state of click. Hope it helps

Upvotes: 0

David
David

Reputation: 84

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

Upvotes: 1

Ben
Ben

Reputation: 244

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

Upvotes: 1

Prakash Kandel
Prakash Kandel

Reputation: 1043

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

Upvotes: 8

Related Questions