0

I'm trying to abstract a portion of this example from using local React hooks to storing the information in Redux.

In particular, the Popover menu requires anchorEl to be specified in order to anchor to a parent <HTMLElement> for positioning. The above example from MaterialUI implements the useState hook to store and change this property:

const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);

When I try to convert this to Redux,

dispatch(accountMenuSlice.actions.setAnchorEl(event.currentTarget));

it ends up trying to store non-serializable <HTMLElement>, which is not advisable, yielding the following warning/error

react_devtools_backend.js:2430 A non-serializable value was detected in an action, in the path: `payload`. 
Value: <button>​…​</button>​ 
Take a look at the logic that dispatched this action:  
{type: "ACCOUNT_MENU_KEY/setAnchorEl", payload: button.MuiButtonBase-root.MuiIconButton-root.MuiIconButton-colorInherit.MuiIconButton-edgeEnd}

What is the canonical React-Redux method to pass elements/references between atomic components without elevating abstractions into parent components?

Ori Drori
  • 183,571
  • 29
  • 224
  • 209
joshp
  • 706
  • 5
  • 22

1 Answers1

0

I ended up just making the popover a child of the button and it went pretty cleanly:

// AccountButton.tsx
export default function AccountButton() {
  const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);

  const handleAccountMenuOpen = (event: React.MouseEvent<HTMLElement>) => {
    setAnchorEl(event.currentTarget);
  };

  return (
    <>
      <IconButton
        edge="end"
        aria-label="account of current user"
        aria-controls="primary-search-account-menu"
        aria-haspopup="true"
        onClick={handleAccountMenuOpen}
        color="inherit"
      >
        <AccountCircle />
      </IconButton>
      <AccountMenu anchorEl={anchorEl} setAnchorEl={setAnchorEl} />
    </>
  );
}

and

// AccountMenu.tsx
export default function AccountMenu(props: {
  anchorEl: HTMLElement;
  setAnchorEl: React.Dispatch<React.SetStateAction<HTMLElement>>;
}) {
  const { anchorEl, setAnchorEl } = props;
...
}
joshp
  • 706
  • 5
  • 22