处理事件 ,用React,和用DOM非常相似,就是些语法差异:

  • React用驼峰法命名而不是纯小写;
  • 事件处理函数的设置使用JSX而不是字符串;

比方说,这是HTML:

  1. <button onclick="activateLasers()">
  2. Activate Lasers
  3. </button>

React,和它略有不同:

  1. <button onClick={activateLasers}>
  2. Activate Lasers
  3. </button>

另一处差异是,在React中,你不能通过返回false来阻止默认行为。你得显示地调用preventDefault()方法。举例来说,在普通HTML中,要想阻止打开新页面的超链接行为的话,你可以这样:

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

在React中,就是这样:

  1. function ActionLink() {
  2. function handleClick(e) {
  3. e.preventDefault();
  4. console.log('The link was clicked.');
  5. }
  6. return (
  7. <a href="#" onClick={handleClick}>
  8. Click me
  9. </a>
  10. );
  11. }

这里,e代表了一个合成事件。React定义了不少合成事件,但你也不用担心浏览器兼容问题因为都是根据w3c文档定义的。这里参考更多的关于合成事件的说明

当你使用es6定义class作为组件时,事件处理器的一种常规的模式是class里面定义方法。例如,Toggle这个组件渲染了一个按钮,允许你在“on”和“off”之间切换:

  1. class Toggle extends React.Component {
  2. constructor(props) {
  3. super(props);
  4. this.state = {isToggleOn: true};
  5. // This binding is necessary to make `this` work in the callback
  6. // ‘this’绑定是必要的
  7. this.handleClick = this.handleClick.bind(this);
  8. }
  9. handleClick() {
  10. this.setState(prevState => ({
  11. isToggleOn: !prevState.isToggleOn
  12. }));
  13. }
  14. render() {
  15. return (
  16. <button onClick={this.handleClick}>
  17. {this.state.isToggleOn ? 'ON' : 'OFF'}
  18. </button>
  19. );
  20. }
  21. }
  22. ReactDOM.render(
  23. <Toggle />,
  24. document.getElementById('root')
  25. );

你要小心那些JSX里面的‘this’。JavaScript中,类方法默认不绑定。要是你忘记了绑定this.handleClick却把它传递给了onClick,那么调用的时候,this就是undefined了。

这可不是React的特有行为,这是JavaScript函数运行机制决定的。通常,要是引用函数时没有()跟着,就像onClick={this.handleClick},你就得用bind()来绑定函数。

要是你讨厌用bind,这也有两种方法绕过它:如果你正在使用实验性“ public class fields ”(公共类属性)语法,你就能使用类属性绑定函数调用:

  1. class LoggingButton extends React.Component {
  2. // This syntax ensures `this` is bound within handleClick.
  3. // Warning: this is *experimental* syntax.
  4. // 这种语法保证this是绑定了handleClick的
  5. // 警告:这是实验性语法(估计不太靠谱)
  6. handleClick = () => {
  7. console.log('this is:', this);
  8. }
  9. render() {
  10. return (
  11. <button onClick={this.handleClick}>
  12. Click me
  13. </button>
  14. );
  15. }
  16. }

这种语法是被 Create React App 从头创立ReactAPP所支持的。

你要是不用这种语法,你也可以使用箭头函数到onClick调用时:

  1. class LoggingButton extends React.Component {
  2. handleClick() {
  3. console.log('this is:', this);
  4. }
  5. render() {
  6. // This syntax ensures `this` is bound within handleClick
  7. return (
  8. <button onClick={(e) => this.handleClick(e)}>
  9. Click me
  10. </button>
  11. );
  12. }
  13. }

这种写法的问题在于:每当LoggingButton被渲染时都会有一个新调用函数产生。大多数这样没毛病。但是,假如调用被当做属性props传递给下级组件,这些组件可能会再额外的重新渲染一番。我们通常推荐构造器中绑定法或者使用类属性法避免这种问题。

事件处理中的参数传递

循环中,常有事件处理时需要传递其他参数的情况。例如,id是行id,下面两种都是可行的:

  1. <button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
  2. <button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

以上分别使用箭头函数和函数原型绑定,一样的都行。

这两种情况下,参数‘e’都代表了React的事件,都会在传递id参数之后被传递。在箭头函数中,我们显示的传递了它,但是在绑定中它被自动传递了。

官网文章 Quick Start :Handling Events