Я использую библиотеку реагировать-муи в своем проекте, где я хотел бы реализовать компонент MenuList, найденный в составе MenuList здесь. Однако в моем приложении я отправляю ref как prop в child component, где у меня есть menu. Вы можете увидеть пример кода и окна здесь.
Когда я отправляю метод ref и setRef как props из родительского компонента следующим образом:
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}
/>
);
}
Для дочернего компонента, у которого есть кнопка меню:
<MenuButton
className = {classes.button}
handleToggle = {handleToggle}
setRef = {setRef}
open = {open}
ref = {ref}
/>
Затем компонент Popper, у которого есть список меню, открывается не в том месте, что вы можете увидеть в примере codesanbox, если вы нажмете на значок 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>
Что я делаю неправильно и как это исправить, или как я могу использовать ref в компоненте stateless, чтобы не отправлять ref как prop?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


ref — это ключевое слово в reactjs. Когда вы используете ref в качестве реквизита, он связывает компонент с объектом ref. Переименуйте его в то, что вам нравится в компоненте FancyButton и компоненте MenuListComposition.
React supports a special attribute that you can attach to any component.
Рабочий пример со ссылкой, переименованной в parentRef в обоих компонентах.
Обновлено:
Как указал Вайбхав Шукла, вы можете использовать React.forwardRef как для FancyButton, так и для MenuListComposition, что, вероятно, является правильным способом сделать это.
Попробуйте еще раз, возможно, я провел некоторые тесты, которые помешали вашим.
Спасибо чувак. Я потратил более 2 часов, пытаясь понять это.
Ref нельзя передавать как реквизит в React. Ссылки обычно назначаются свойству экземпляра при создании компонента, чтобы на них можно было ссылаться во всем компоненте. Более того, когда ссылка передается элементу в рендере, ссылка на узел становится доступной в текущем атрибуте ссылки.
React предоставляет метод React.forwardRef для передачи ссылок в иерархии компонентов. Обычно в этом нет необходимости для большинства компонентов приложения. Однако это может быть полезно для некоторых видов компонентов, особенно в повторно используемых библиотеках компонентов. Читать о впередRef
const ButtonWrapper = React.forwardRef((props, ref) => (
<button ref = {ref}>
{props.children}
</button>
));
// You can now get a ref directly to the DOM button:
const ref = React.createRef();
<ButtonWrapper ref = {ref}>Click me!</ButtonWrapper>;
Это работает, но раздражает создание предупреждений в журнале консоли в процессе разработки Warning: [object Object]: 'ref' is not a prop., что загрязняет тестовую консоль.
Ваш пример показывает ту же ошибку, что и мой. Список меню открывается под первой кнопкой, а не под последней, как должно быть.