按 Enter 反应组件
React component with pressing Enter
我有一些 React 组件,需要使用 "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
,但当按下 Enter 时,控制台再次显示 fired
。
您永远不会取消绑定事件处理程序。问题是 this.enter.bind(this)
和 this.enter
是不同的函数,因为 Function.prototype.bind 从原始函数创建了新的 "wrapper" 函数。
尝试这样的事情:
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
提供相同的功能。
this.enter.bind(this)
returns 一个 new 函数,与 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);
}
(componentDidMount
中也不需要您的 removeEventListener
。)
由于您使用的是 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
预设的一部分)。
我有一些 React 组件,需要使用 "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
,但当按下 Enter 时,控制台再次显示 fired
。
您永远不会取消绑定事件处理程序。问题是 this.enter.bind(this)
和 this.enter
是不同的函数,因为 Function.prototype.bind 从原始函数创建了新的 "wrapper" 函数。
尝试这样的事情:
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
提供相同的功能。
this.enter.bind(this)
returns 一个 new 函数,与 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);
}
(componentDidMount
中也不需要您的 removeEventListener
。)
由于您使用的是 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
预设的一部分)。