处理事件

本文是本人自己辛苦翻译的,请转载的朋友注明,翻译于Z.MJun的简书 ,感谢!<翻译不容易啊>


翻译于2017年6月26日,原文


处理事件的React元素,与DOM元素处理事件相似。

  • React 事件使用驼峰式命名,不要使用全小写。
  • 使用JSX来传一个事件执行函数,不要使用字符串。
    HTML的样式如下:
<button onclick="activateLasers()">
  Activate Lasers
</button>

在React使用以下方法

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

另一个不同点,在react中不能使用返回false。必须调用preventDefault。Html如下:

<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 spec。所以不需要担心浏览器兼容问题。想了解更多查看SyntheticEvent

当使用React的时候,不需要如DOM元素调用addEventListener方法添加监听者。只需要,在初始化渲染的时候提供一个监听者。

当使用ES6类来定义一个组件,常见的模式是将事件处理程序作为类中的一个方法。如,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')
);

Try it on CodePen.
在JSX的回调,this的含义需要反复理解。在JS里面,类方法中没有默认绑定。如果你忘记了绑定this.handleClick,和点击onClickthis将会警告未定义。

这个并不是React特有的行为。这是JS的函数的一部分。一般来说,如果你是一个没有()方法后,如onclick = {this.handleclick },你应该绑定方法。

可以使用以下两个方法来绑定时间。如果使用初始化绑定(property initializer syntax),可以使用初始化的属性来绑定回调方法。

class LoggingButton extends React.Component {
  // This syntax ensures `this` is bound within handleClick.
  // Warning: this is *experimental* syntax.
  handleClick = () => {
    console.log('this is:', this);
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        Click me
      </button>
    );
  }
}

这个语法是默认能用在Create React App下的。
如果你不想使用这个方法,还可以使用回调中动态加载方法。

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。多数情况下,都可以的。但是,如果这个回调是要穿个低级的组件,这些组件就需要创建额外的重新渲染。比较推荐在constructor绑定或者使用初始化定义,来避免这个实现问题。

推荐阅读更多精彩内容