Entonces tengo este componente basado en la clase:

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

En el constructor estoy creando ref, y luego quiero pasarlo al componente DropdownBox, que se representa. En el componente DropdownBox traté de usar ganchos de reacción, pero creo que no es así. ¿Cómo hacerlo correctamente? Tenga en cuenta que no quiero cambiar mi componente funcional a clase.

Aquí está el código del componente 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>
  )
}
1
WhoIsDT 10 may. 2019 a las 12:25

3 respuestas

La mejor respuesta

Puede utilizar reenviar referencias para obtener una referencia al elemento subyacente fuera del componente secundario. Por ejemplo:

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>
));

Luego en OptionsMenu:

 return (
      <DropdownBox ref={this.dropdownBoxRef} styles={this.props.styles}>
        <ul className='OptionsList'>{options}</ul>
      </DropdownBox>
)
1
dashton 10 may. 2019 a las 09:44

Puede asignarle al cuadro desplegable una función que establecerá la referencia. Para hacer esto, puede agregar en su componente de menú una función como la siguiente:

const onDropdownRef = (ref) => {
    this.dropdownBoxRef.current = ref;
}

Luego asigna esta función a su componente desplegable de la siguiente manera: <DropdownBox onRef={this.onDropdownRef} styles={this.props.styles}>

Luego, finalmente, en su componente desplegable, le da esta función al div de la siguiente manera: <div ref={props.onRef} className='DropdownBox-Container' style={props.styles}>

Esto asegurará que su menú tendrá una referencia al div superior del cuadro desplegable.

0
ApplePearPerson 10 may. 2019 a las 09:36

Simplemente asigne el accesorio reference en su componente DropdownBox al accesorio ref del div del que desea la referencia.

const dropdownBox = props => {
  return (
    <div ref={props.reference} className='DropdownBox-Container' style={props.styles}>
      { /* ... */ }
    </div>
  )
}

React asignará el componente a la variable dropdownRef por sí solo.

0
Rallen 10 may. 2019 a las 09:44