代码之家  ›  专栏  ›  技术社区  ›  AlekseyDanchin

按Enter键反应组件

  •  2
  • AlekseyDanchin  · 技术社区  · 9 年前

    我有一些react组件,需要使用“输入”功能。

    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 回复  |  直到 9 年前
        1
  •  2
  •   T.J. Crowder    9 年前

    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 在您的transpiler(在巴贝尔,他们目前是 stage-2 预设)。

        2
  •  2
  •   dfsq    9 年前

    您永远不会解除事件处理程序的绑定。问题是 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 .