Итак, у меня есть этот компонент на основе класса:
import React, { Component } from 'react'
import './OptionsMenu.sass'
import DropdownBox from '../DropdownBox/DropdownBox'
import Icon from '../Icon/Icon'
class OptionsMenu extends Component {
constructor(){
super()
this.dropdownBoxRef = React.createRef()
}
handleClickOutside = event => {
if (this.dropdownBoxRef && !this.dropdownBoxRef.current.contains(event.target)) {
this.props.close()
}
}
componentDidMount() {
document.addEventListener('mousedown', this.handleClickOutside)
}
componentWillUnmount() {
document.removeEventListener('mousedown', this.handleClickOutside)
}
render() {
const options = this.props.options.map(option => (
<li className='OptionsList-Element'>
<div className='OptionsList-ElementIcon'>
<Icon name = {option.icon} />
</div>
<span>{option.label}</span>
</li>
))
return (
<DropdownBox reference = {this.dropdownBoxRef} styles = {this.props.styles}>
<ul className='OptionsList'>{options}</ul>
</DropdownBox>
)
}
}
export default OptionsMenu
В конструкторе я создаю ref, а затем хочу передать его компоненту DropdownBox, который отображается. В компоненте DropdownBox я пытался использовать хуки реагирования, но я думаю, что это неправильный путь. Как сделать это правильно? Обратите внимание, я не хочу переключать свой функциональный компонент на классовый!
Вот код компонента DropdownBox:
const dropdownBox = props => {
const dropdownBoxRef = useRef(props.reference)
return (
<div ref = {dropdownBoxRef} className='DropdownBox-Container' style = {props.styles}>
<div className='DropdownBox'>
<div className='DropdownBox-Triangle' />
{props.children}
</div>
</div>
)
}



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


Вы можете дать dropdownBox функцию, которая установит ссылку. Для этого вы можете добавить в свой компонент меню функцию, подобную следующей:
const onDropdownRef = (ref) => {
this.dropdownBoxRef.current = ref;
}
Затем вы передаете эту функцию своему раскрывающемуся компоненту следующим образом: <DropdownBox onRef = {this.onDropdownRef} styles = {this.props.styles}>
Затем, наконец, в раскрывающемся компоненте вы передаете эту функцию div следующим образом:
<div ref = {props.onRef} className='DropdownBox-Container' style = {props.styles}>
Это гарантирует, что в вашем меню будет ссылка на верхний div из раскрывающегося списка.
Просто назначьте реквизит reference в компоненте DropdownBox реквизиту ref компонента div, ссылку на который вы хотите получить.
const dropdownBox = props => {
return (
<div ref = {props.reference} className='DropdownBox-Container' style = {props.styles}>
{ /* ... */ }
</div>
)
}
React самостоятельно назначит компонент переменной dropdownRef.
Вы можете использовать пересылка ссылок, чтобы получить ссылку на базовый элемент вне дочернего компонента. Например:
const DropdownBox = React.forwardRef((props, ref) => (
<div ref = {ref} className='DropdownBox-Container' style = {props.styles}>
<div className='DropdownBox'>
<div className='DropdownBox-Triangle' />
{props.children}
</div>
</div>
));
Затем в OptionsMenu:
return (
<DropdownBox ref = {this.dropdownBoxRef} styles = {this.props.styles}>
<ul className='OptionsList'>{options}</ul>
</DropdownBox>
)