Идея заключалась в том, чтобы создать раскрывающийся список, который прослушивает щелчки мыши за пределами своих элементов, а затем уничтожается. Я могу добиться желаемого эффекта, однако я не могу очищать события каждый раз, когда элементы раскрывающегося списка уничтожаются (после нескольких открытий и закрытий раскрывающегося списка я регистрирую около десяти кликов, даже если раскрывающийся список закрыт), пытаясь ознакомиться с реагируйте, чтобы ваша помощь была оценена

Моя попытка, вызов компонента

RequestDropDown.create(row.id).show({
      room_id: row.id,
      setTheState: this.setTheState
    });

Создание элемента по клику

class RequestDropDown extends Component {
  static create(props = {}) {
    const containerElement = document.createElement('div');
    containerElement.classList.add('RequestDropDown_container');
    document.getElementById(`table_dots_btn_${props}`).after(containerElement);
    return render(
      <RequestDropDown createDropDownProps={props} />,
      containerElement
    );
  }

Конструктор и методы


  constructor() {
    super();
    this.myRef = null;

    this.setmyRefRef = (element) => {
      this.myRef = element;
    };

    this.state = {
      isOpen: false,
      showDropDownProps: {},
    };
    this.handleClick = this.handleClick.bind(this);
    this.handleClickOutside = this.handleClickOutside.bind(this);
    this.show = this.show.bind(this);
  }
  componentWillMount() {
     document.addEventListener('mousedown', this.handleClick, false);

  }

  componentWillUnMount() {
    window.removeEventListener('mousedown', this.handleClick, false);
  }

  handleClick= (e)=> {
      if(this.myRef.contains(e.target)) {
          console.log('you clicked inside')
          return;
      }
      this.handleClickOutside()
  }

  handleClickOutside= async () =>{
    console.log('the click is  outside');
    this.myRef = null;
    var element = await document.getElementsByClassName('RequestDropDown_container');
    if (element.length == 0) {
        return
    }
    await element[0].parentNode.removeChild(element[0]); // tried this too    unmountComponentAtNode(element[0]);
    this.setState({
        isOpen: false
    })
  }


  async show(props = {}) {

    await this.setState({ isOpen: true, room_id: props.room_id, setTheState: props.setTheState });

  }

Рендер


  render() {
    const { setTheState } = this.state;
    console.log(this.myRef)

    return (this.state.isOpen === true ?
      <div id="drop_down_node" ref={this.setmyRefRef}>
        <div class="confirm_modal_content">
          <div className="dropdown-content">
            <a>Room settings</a>
            <a onClick={setTheState}>standard room</a>
            <a

            // onClick={() => handleReject(row)}
            >
              deluxe room
            </a>
          </div>
        </div>
      </div> : null
    );
  }
}

export default RequestDropDown;
1
bihire boris 15 Апр 2020 в 10:08
ComponentWillMount() устарела, используйте componentDidMount()
 – 
HermitCrab
15 Апр 2020 в 10:15
Когда вы используете React, не связывайтесь с DOM, используя getElementsByClassName и removeChild
 – 
HermitCrab
15 Апр 2020 в 10:20
Пытался изменить его, безуспешно @HermitCrab, пожалуйста, я открыт для предложений, которые были моей попыткой, также мой единственный вариант - прикрепить компонент туда, где он мне нужен.
 – 
bihire boris
15 Апр 2020 в 10:30
Я также заметил, что вы прикрепляете свой eventListener к документу, а затем удаляете его из окна. Вы должны удалить его из того же элемента (т.е. документа)
 – 
HermitCrab
15 Апр 2020 в 10:33
Я тоже пробовал это, братан @HermitCrab, просто я сошел с ума
 – 
bihire boris
15 Апр 2020 в 10:38

1 ответ

componentWillMount() {
    document.addEventListener('mousedown', this.handleClick, false);

}

componentWillUnMount() {
    document.removeEventListener('mousedown', this.handleClick, false);
}
0
Rajan 15 Апр 2020 в 10:15