反应JS removeEventListener不触发

时间:2019-10-09 09:44:56

标签: javascript reactjs

我有两个函数,其中一个包含addEventListener(“ click”),另一个函数删除

show() {
    console.log("SHOW FUNCTION")
    this.setState({
        listVisible: true
    })

    document.addEventListener("click", this.hide.bind(this));
}

hide() {
    console.log("HIDE FUNCTION")
    this.setState({
        listVisible: false
    })

    document.removeEventListener("click", this.hide.bind(this));
}

在初次单击时,将show()触发,状态将按预期进行更新,并且在进行第二次单击后,将hide()触发并且一切正常。

当我再次单击(第三次单击)时,console.logs列表首先显示show(),然后是hide()的两个日志,因此当状态为true时,将状态设置为false,就像第一个序列一样。

我不确定为什么会发生这种情况,几乎就像removeEventListener没有触发一样。也可能是“ this”的错误上下文吗?

这是我的组件代码:

renderListItems() {
    const items = [];
    for (var i = 0; i < this.props.list.length; i++) {
        const item = this.props.list[i];
        items.push(<div className="option" onClick={() => this.select(item)}>
            <span>{item.name}</span>
            <i className="fa fa-check"></i>
        </div>);
    }
    return items;
}

render() {
    console.log("give me", this.state.listVisible)
    return (
        <div className={"dropdown-container" + (this.state.listVisible ? " show" : "")}>
            <div className={"dropdown-display" + (this.state.listVisible ? " clicked": "")} onClick={() => this.show()}>
                <span>
                    {this.state.selected.name}
                </span>
                <i className="fa fa-angle-down"></i>
            </div>
            <div className="dropdown-list">
                <div>
                    {this.renderListItems()}
                </div>
            </div>
        </div>
    )
}

2 个答案:

答案 0 :(得分:2)

每次调用.bind都会创建一个新函数。创建组件后,应创建绑定函数一次,以便removeEventListener可以找到该函数。

您可以在ES6中绑定类方法:

hide = () => {

}

或者在您的构造函数中完成

constructor(...args) {
   super(...args);
   this.hide = this.hide.bind(this);
}

然后,您的事件监听器可以简单地引用已经绑定的函数this.hide

答案 1 :(得分:0)

我找到了一个解决方案-删除hide函数,删除所有绑定并更新select函数中的状态。

import React, {Component} from 'react'
import classNames from 'classnames';

import './style.scss'

export default class FormCustomSelect extends Component {
    constructor(props) {
        super(props);

        this.state = {
            listVisible: false,
            display: "",
            selected: this.props.selected
        }
    }

    select(item) {
         this.setState({ 
            selected: item,
            listVisible: false
         })
    }

    show() {        
        this.setState({
            listVisible: true
        })
    }

    renderListItems() {
        const items = [];
        for (var i = 0; i < this.props.list.length; i++) {
            const item = this.props.list[i];
            items.push(<div className="option" onClick={() => this.select(item)}>
                <span>{item.name}</span>
                <i className="fa fa-check"></i>
            </div>);
        }
        return items;
    }

    render() {
        console.log("give me", this.state.listVisible)

        return (
            <div className={"dropdown-container" + (this.state.listVisible ? " show" : "")}>
                <div className={"dropdown-display" + (this.state.listVisible ? " clicked": "")} onClick={() => this.show()}>
                    <span>
                        {this.state.selected.name}
                    </span>
                    <i className="fa fa-angle-down"></i>
                </div>
                <div className="dropdown-list">
                    <div>
                        {this.renderListItems()}
                    </div>
                </div>
            </div>
        )
    }

}