【问题标题】:How to clear events listeners in react after removing an element from the DOM从DOM中删除元素后如何清除事件监听器
【发布时间】:2023-03-29 19:36:01
【问题描述】:

这个想法是创建一个下拉列表来监听其元素之外的鼠标点击,然后将其销毁。 我能够达到我想要的效果但是每次下拉元素被破坏时我都无法清除事件 (经过几次打开和关闭下拉菜单后,即使关闭了下拉菜单,我也注册了十次点击) 尝试熟悉反应,因此感谢您的帮助

我的尝试, 调用组件

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;

【问题讨论】:

  • componentWillMount() 已弃用,请使用 componentDidMount()
  • 当你使用 React 时,不要使用 getElementsByClassName 和 removeChild 来搞乱 DOM
  • 试过改变它,没有成功@HermitCrab,请我愿意接受我尝试过的建议,我唯一的选择是将组件附加到我需要的地方
  • 我还注意到您将 eventListener 附加到文档,然后将其从窗口中删除。您必须从同一个元素(即文档)中删除它
  • 我也试过了兄弟@HermitCrab,那只是我发疯了

标签: javascript reactjs react-redux react-router


【解决方案1】:
componentWillMount() {
    document.addEventListener('mousedown', this.handleClick, false);

}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-16
    • 2021-05-24
    • 2021-11-21
    • 2011-05-23
    相关资源
    最近更新 更多