按Enter键反应组件

时间:2016-12-26 10:30:27

标签: javascript reactjs events components enter

我有一些反应组件,需要使用"输入"功能

class MyComponent extends Component {
    componentDidMount() {
        console.log('componentDidMount');
        document.removeEventListener('keypress', this.enter);
        document.addEventListener('keypress', this.enter.bind(this));
    }

    componentWillUnmount() {
        console.log('componentWillUnmount');
        document.removeEventListener('keypress', this.enter);
    }

    render() {
        return (...);
    }

    enter(target) {
        if (target.charCode === 13) {
            console.log('fired');
            /* after that component unmounted */
        }
    }
}

控制台日志显示:

componentDidMount
fired
componentWillUnmount

,但按回车键再次显示fired

2 个答案:

答案 0 :(得分:2)

您永远不会取消绑定事件处理程序。问题是this.enter.bind(this)this.enter是不同的函数,因为Function.prototype.bind创建了新的"包装器"从原来的功能。

尝试这样的事情:

class MyComponent extends Component {
    constructor () {
        this.enter = this.enter.bind(this)
    }

    componentDidMount() {
        console.log('componentDidMount');
        document.removeEventListener('keypress', this.enter);
        document.addEventListener('keypress', this.enter);
    }

    componentWillUnmount() {
        console.log('componentWillUnmount');
        document.removeEventListener('keypress', this.enter);
    }

    render() {
        return (...);
    }

    enter(target) {
        if (target.charCode === 13) {
            console.log('fired');
            /* after that component unmounted */
        }
    }
}

注意,您需要为addEventListenerremoveEventListener提供相同的功能。

答案 1 :(得分:2)

this.enter.bind(this)会返回函数,该函数与this.enter的功能不同。因此,您的removeEventListener会被忽略,因为该特定功能不在事件列表中。

记住this.enter.bind(this)的结果,并在删除时使用它。

componentDidMount() {
    console.log('componentDidMount');
    this.boundEnter = this.enter.bind(this);
    document.addEventListener('keypress', this.boundEnter);
}

componentWillUnmount() {
    console.log('componentWillUnmount');
    document.removeEventListener('keypress', this.boundEnter);
}

removeEventListener也不需要componentDidMount。)

由于您使用的是ES2015 +语法,我假设您正在进行转换。如果是,您可以使用箭头功能而不是enter的方法:

class MyComponent extends Component {
    componentDidMount() {
        console.log('componentDidMount');
        document.addEventListener('keypress', this.enter);
    }

    componentWillUnmount() {
        console.log('componentWillUnmount');
        document.removeEventListener('keypress', this.enter);
    }

    render() {
        return (...);
    }

    enter = target => {
        if (target.charCode === 13) {
            console.log('fired');
            /* after that component unmounted */
        }
    };
}

这要求您在浏览器中启用class properties处理(在Babel中,它们目前是stage-2预设的一部分)。