Search code examples
reactjstypescripteventsrendermaterial-table

Prevent onClick event to happen in all rows instead of one sigle row per click


I have a table in which a I have a button that appears in every single row. This button displays an onClick event which adds two buttons elements below.

What happens : when I click on a button the onClick event is done in every single row instead of just the only one I clicked.

What I expect to happen: when clicking to the button in one row the event it's done on that single row.

Note : I am using material table and in one the of the columns I have a render method and the structure of the button is like the following:

<Button
              disableRipple
              className={(classes.buttonState, classes.textButtonStatePending)}
              onMouseEnter={handleHover} //makes the buttons appear
              onMouseLeave={handleHoverAway} //makes the buttons dissapear
              onClick={handleHover}
              onChange={handleHover}
            >
              Pending
            </Button>

This is my event that makes hover over the button and it must show my components:

const handleHover = (): void => {
    setShowButtonGroup(true);
  };

Solution

  • So looking at the docs, it looks like a custom render method for a table column looks like this:

    render: rowData => <YourCustomComponent />
    

    In your case, you are rendering a <Button> with a bunch of handlers, including onClick. Assuming your rowData has some kind of unique value like id, you can use this to tie the button click to the row:

    render: rowData => <Button onClick={() => handleClick(row.id)}>Pending</Button>
    

    I've added a separate click handler for this, it's not necessary but it helps to keep things separate. So now you need a click handler that is 'row aware' - normally this might look something like this:

    const handleClick = (id): void => {
        setVisibleRowId(id)
     };
    

    Finally, you use this id wherever you are rendering the buttons that you want to show/hide, so if it's in another column render method:

    render: rowData => rowData.id === visibleRowId ? <Button>My row was clicked</Button> : undefined
    

    ETA: regarding your additional question

    I don't know how to pass the key to the button either : onClick={ handleHover(time.teamMember[1])}

    This will call your handleHover function on every render, which you don't want. You have wrap this call in a new function - i.e. pass a function that is invoked only on click:

    onClick={() => handleHover(time.teamMember[1])}