I am using a react-mui library in my project where I would like to implement a MenuList
component, found under MenuList composition here. In my application though I am sending a ref
as prop
down to a child component
where I have a menu
. You can see the codesandbox example here.
When I send a ref
and a setRef
method as props
from a parent component like this:
state = {
open: false,
ref: React.createRef()
};
setRef = element => {
this.setState({ ref: element });
};
handleToggle = () => {
this.setState(state => ({ open: !state.open }));
};
handleClose = () => {
this.setState({ open: false });
};
render() {
return (
<MenuListComposition
setRef={this.setRef}
handleToggle={this.handleToggle}
handleClose={this.handleClose}
open={this.state.open}
ref={this.state.ref}
/>
);
}
To a child component that has a menu button:
<MenuButton
className={classes.button}
handleToggle={handleToggle}
setRef={setRef}
open={open}
ref={ref}
/>
Then the Popper component which has a menu list opens at a wrong place, which you can see in the codesanbox example if you click on the TOGGLE MENU GROW button
.
<Popper open={open} anchorEl={ref} transition disablePortal>
{({ TransitionProps, placement }) => (
<Grow
{...TransitionProps}
id="menu-list-grow"
style={{
transformOrigin:
placement === "bottom" ? "center top" : "center bottom"
}}
>
<Paper>
<ClickAwayListener onClickAway={handleClose}>
<MenuList>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem>
</MenuList>
</ClickAwayListener>
</Paper>
</Grow>
)}
</Popper>
What am I doing wrong and how to fix this, or how can I use ref
in a stateless
component where I would avoid sending down ref
as a prop
?
ref
is a keyword in reactjs. When you use ref
as a prop it linked the component to the ref object. Rename it to whatever you like on FancyButton
component and MenuListComposition
component.
From react documentation.
React supports a special attribute that you can attach to any component.
Working example with ref renamed to parentRef in both components.
EDIT:
As pointed it out by Vaibhav Shukla, you can use React.forwardRef
on both FancyButton
and MenuListComposition
which is probably the correct way to do this.