绑定事件

作者: 编码的哲哲 | 来源:发表于2017-02-16 11:51 被阅读56次

    在react的elements上绑定事件和在dom上绑定事件极为相似,但是还是有一些语法上的不同:
    ** react的事件用驼峰命名法 ,而不是小写命名法 **
    ** 你需要传递一个函数名作为一个事件而不是一个字符串 **
    比如在传统html中:

    <button onclick="activateLasers()">
      Activate Lasers
    </button>
    

    在react中会有些许不同:

    <button onClick={activateLasers}>
      Activate Lasers
    </button>
    

    另外一个不同是你不能返回一个false去阻止默认事件,你必须调用preventDefault这个函数。比如,在html中,为了去阻止默认的link跳转到其他页面的事件,你可以这样写:

    <a href="#" onclick="console.log('The link was clicked.'); return false">
      Click me
    </a>
    

    而在react中,你可以改成这样:

    function ActionLink() {
      function handleClick(e) {
        e.preventDefault();
        console.log('The link was clicked.');
      }
    
      return (
        <a href="#" onClick={handleClick}>
          Click me
        </a>
      );
    }
    

    在这里,e代表了一系列综合的事件。react根据w3c的标准定义了这些事件,所以不用去担心浏览器的兼容问题。
    在 react的机制中,你不需要去用addEventListener去给dom节点绑定事件,你仅仅只需在这个元素创建时提供一个监听器就行。
    当你使用ES6的class去定义一个组件时,一个通用的模式是将一个方法定义为一个事件处理函数。比如,下面这个Toggle组件渲染了一个允许用户切换ON或OFF的按钮:

    class Toggle extends React.Component {
      constructor(props) {
        super(props);
        this.state = {isToggleOn: true};
    
        // This binding is necessary to make `this` work in the callback
        this.handleClick = this.handleClick.bind(this);
      }
    
      handleClick() {
        this.setState(prevState => ({
          isToggleOn: !prevState.isToggleOn
        }));
      }
    
      render() {
        return (
          <button onClick={this.handleClick}>
            {this.state.isToggleOn ? 'ON' : 'OFF'}
          </button>
        );
      }
    }
    
    ReactDOM.render(
      <Toggle />,
      document.getElementById('root')
    );
    

    你需要注意this在JSX中的含义。在javascript中,类中的方法不是默认是不受绑定的,如果你忘了去显式的绑定并且将其传递给onClick事件,this将会被当作未定义,当这个类函数被执行的时候。
    这不是react的原因,而是javascript本身设计的原因* 【如果你有疑惑,推荐你看看《你不知道的javascript上卷》】*。通常,要是你将一个函数名赋值给了一个事件,比如onClick={this.handleClick},这时你就需要显式的绑定它。
    如果关于绑定这个问题让你变的困扰的话,这里有两个方法可以让你避免出错:

    1. 使用赋值尖头函数的方式:
    class LoggingButton extends React.Component {
      
      handleClick = () => {
        console.log('this is:', this);
      }
    
      render() {
        return (
          <button onClick={this.handleClick}>
            Click me
          </button>
        );
      }
    }
    
    1. 在element上使用尖头函数绑定:
    class LoggingButton extends React.Component {
      handleClick() {
        console.log('this is:', this);
      }
    
      render() {
        // This syntax ensures `this` is bound within handleClick
        return (
          <button onClick={(e) => this.handleClick(e)}>
            Click me
          </button>
        );
      }
    }
    

    用第二种方法问题在于不同的回调函数会引发LoggingButton的再次渲染。在大多数情况下,这时极好的特性,但是如果这个会掉函数作为props被传递给子组件呢?这些子组件可能会引发我们不希望的渲染。所以我们建议显示的绑定或者第一种方法,以此来避免性能上的问题。

    相关文章

      网友评论

        本文标题:绑定事件

        本文链接:https://www.haomeiwen.com/subject/wgwcwttx.html