sonan
sonan

Reputation: 101

Reactjs onMouseOver and onMouseOut event loop in a try for Popover

I am trying to create a React Material Popover(https://material-ui.com/api/popover/) element, to be shown when user hovers mouse over a TableRow (https://material-ui.com/api/table-row/), and to be hidden when user hovers mouse out of the TableRow.

What I have already tried :

const handlePopoverOpen = event => {
  setAnchorEl(event.currentTarget);
};


const handlePopoverClose = event => {
    setAnchorEl(null);
  };

const open = Boolean(anchorEl);

. . .

<TableRow
   selected={props.selected === key ? true : false}
   hover={true}
   key={key} className={classes.tableBodyRow}
   onClick={() => props.onSelectChange(key, prop[0], prop[1])}
   onMouseOver={handlePopoverOpen}
   onMouseOut={handlePopoverClose}            
>

. . .

<Popover
    id="mouse-over-popover"
    open={open}
    anchorEl={anchorEl}
    anchorOrigin={{
      vertical: 'bottom',
      horizontal: 'center',
    }}
    transformOrigin={{
      vertical: 'top',
      horizontal: 'left',
    }}
    onClose={handlePopoverClose}
  >
    I use Popover
  </Popover>

Popover appears when mouse is hovered over the TableRow, but then it keeps blinking like there is an infinite loop of onMouseOver() and onMouseOut(). I have been investigating this issue for hours and I cant find the explanation of this issue. I would appreciate if someone could help!

Here is a code live demo: https://codesandbox.io/s/heuristic-banach-071f3?fontsize=14&hidenavigation=1&theme=dark

Upvotes: 4

Views: 7060

Answers (2)

Jaanus
Jaanus

Reputation: 16531

After settings pointerEvents to none, it started working properly.

sx={{
       pointerEvents: 'none',
}}

Full example

<Popover
          open={avatarOpen}
          anchorEl={anchorEl}
          onClose={handlePopoverClose}
          sx={{
              pointerEvents: 'none',
          }}
</Popover>

Upvotes: 2

NinaW
NinaW

Reputation: 658

Did you check the 'Mouse over interaction' section at https://material-ui.com/components/popover/?

I can't see the rest of your code, so difficult to advice on the exact changes you need to make, but your solution is a bit different from the example:

<Typography
  aria-owns={open ? 'mouse-over-popover' : undefined}
  aria-haspopup="true"
  onMouseEnter={handlePopoverOpen}
  onMouseLeave={handlePopoverClose}
>
  Hover with a Popover.
</Typography>

ADDED:

After seeing the whole code, I would make these changes:

  1. Make your tableData array an array of objects rather than an array of arrays
const tableData = [{name: "Nick", age: 15}, {name: "George", age: 10}, {name: "John", age: 11}];
  1. Change your code inside tableBody to reflect this
<TableBody>
  {tableData.map(data => {
    return (
      <TableRow
        key={data.name}
        hover={true}
        aria-haspopup="true"
        onMouseOver={handlePopoverOpen}
        onMouseOut={handlePopoverClose}
      >
        <TableCell>{data.name}</TableCell>
        <TableCell>{data.age}</TableCell>
      </TableRow>
    )
  })}
</TableBody>

NOTE: the key has to be unique, so no duplicate names. Best option is to add an unique id to the object and use it as the key.

{id: 1, name: "Nick", age: 15}

Then test the popover!

Upvotes: 2

Related Questions