'React on hover show buttons

I have a React application on which I would like to implement functionality when the mouse is in the appropriate row (on hover), and then a button for editing and deleting in the corresponding row is displayed. I implemented something, but when the mouse is in a row, these buttons appear in all rows.

This is my code:

import React from 'react';

const Contact = (props) => {
const array = Object.entries(props);

const classes = document.getElementsByClassName('btn');

const display = (isShown) => {
    if (isShown) {
        for (let i = 0; i < classes.length; i++) {
            classes[i].style.display = 'block'
        }
    }
    else {
        for (let i = 0; i < classes.length; i++) {
            classes[i].style.display = 'none'
        }
    }
};

return (
    <table className="table table-light">
        <thead>
            <tr>
                <th scope="col">#</th>
                <th scope="col">Name</th>
                <th scope="col">Continent/Country</th>
                <th scope="col">eMail</th>
                <th scope="col">FreeGuyz</th>
                <th scope="col">Instagram</th>
                <th scope="col">Twitter</th>
            </tr>
        </thead>
        <tbody>
            {array.map((contact, index) => (
                <tr onMouseEnter={() => { display(true) }} onMouseLeave={() => display(false)} key={index}>
                    <th scope='row'>{index += 1}</th>
                    <td>{contact[1].name}</td>
                    <td>{contact[1].continentAndCountry}</td>
                    <td>{contact[1].email}</td>
                    <td>{contact[1].accountNameForFreeGuyz}</td>
                    <td>{contact[1].accountNameForInstagram}</td>
                    <td>{contact[1].accountNameForTwitter}</td>
                    <td>
                        <button style={{ marginRight: 5 + 'px' }} className='btn btn-warning' id={contact.id}>Edit</button>
                        <button className='btn btn-danger' id={contact.id} type='submit'>Delete</button>
                    </td>
                </tr>
            ))}
        </tbody>
    </table>
);
};

  export default Contact;

I will be glad if someone can help me.



Solution 1:[1]

My suggestion:

Create a separate component for each table row,

Inside it, create a state which represents isHovered.

Set it on or off on mouseenter - mouseleave.

    const ContactRow = ({ contact, index }) => {
  const [isHovered, setHovered] = useState(false);
  // ... logic
  return (
    <tr
      onMouseEnter={() => {
        setHovered(true);
      }}
      onMouseLeave={() => setHovered(false)}
      key={index}
    >
      <th scope="row">{(index += 1)}</th>
      <td>{contact[1].name}</td>
      <td>{contact[1].continentAndCountry}</td>
      <td>{contact[1].email}</td>
      <td>{contact[1].accountNameForFreeGuyz}</td>
      <td>{contact[1].accountNameForInstagram}</td>
      <td>{contact[1].accountNameForTwitter}</td>
        <td>
          {isHovered && <><button
            style={{ marginRight: 5 + "px" }}
            className="btn btn-warning"
            id={contact.id}
          >
            Edit
          </button>
          <button className="btn btn-danger" id={contact.id} type="submit">
            Delete
          </button></>}
        </td>
    </tr>}

Solution 2:[2]

Unless there is a reason you need to do this in JS, I would recommend to use CSS to solve these kind of problems. Just make sure you can select the edit button (i.e., give it a class of edit in this example):

tr button.edit {
  display: none;
}

tr:hover button.edit {
  display: initial;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Oli