我有一些反应组件,需要使用"输入"功能
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
。
答案 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 */
}
}
}
注意,您需要为addEventListener
和removeEventListener
提供相同的功能。
答案 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
预设的一部分)。