【问题标题】:React component with pressing Enter按 Enter 反应组件
【发布时间】:2016-12-26 10:30:26
【问题描述】:

我有一些反应组件,需要使用“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

【问题讨论】:

    标签: javascript reactjs events components enter


    【解决方案1】:

    this.enter.bind(this) 返回一个 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 预设的一部分)。

    【讨论】:

      【解决方案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 提供same 函数。

      【讨论】:

      • 您的版本可以工作,但在“输入”中需要访问 this.props 和 this.state,这就是为什么我更喜欢第一个答案。
      • 您可以同时访问this.propsthis.state
      猜你喜欢
      • 2012-02-13
      • 2023-04-05
      • 1970-01-01
      • 2021-02-19
      • 2021-12-20
      • 2021-07-18
      • 2021-11-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多