React绑定onClick为什么要用箭头函数?

最近开始学习react,刚看完官方的教程TicTacToe,对onClick事件绑定的语法不是很理解,所以来这里提问,求大家帮忙解答。下面是官方教程里的代码:

class Board extends React.Component {
  constructor() {
    super();
    this.state = {
      squares: Array(9).fill(null),
      xIsNext: true,
    };
  }

  handleClick(i) {
    const squares = this.state.squares.slice();
    squares[i] = this.state.xIsNext ? 'X' : 'O';
    this.setState({
      squares: squares,
      xIsNext: !this.state.xIsNext,
    });
  }

  renderSquare(i) {
    return (
      <Square
        value={this.state.squares[i]}
        onClick={() => this.handleClick(i)}
      />
    );
  }

  render() {
    const status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');

    return (
      <div>
        <div className="status">{status}</div>
        <div className="board-row">
          {this.renderSquare(0)}
          {this.renderSquare(1)}
          {this.renderSquare(2)}
        </div>
        <div className="board-row">
          {this.renderSquare(3)}
          {this.renderSquare(4)}
          {this.renderSquare(5)}
        </div>
        <div className="board-row">
          {this.renderSquare(6)}
          {this.renderSquare(7)}
          {this.renderSquare(8)}
        </div>
      </div>
    );
  }
}

其中这一段:

  renderSquare(i) {
    return (
      <Square
        value={this.state.squares[i]}
        onClick={() => this.handleClick(i)}
      />
    );
  }

绑定onClick事件时,为什么不直接写成onClick={this.handleClick(i)}呢?

箭头函数等同于

function() {
  return this.handleClick(i);
}

的话,那么我的理解两种写法应该是等效的,但第二种貌似过不了编译。刚入门很多不懂,求大家解答一下,十分感谢!

阅读 27.7k
17 个回答

这些老铁都说的什么啊。。
如果 直接写

onClick={this.handleClick(i)} 

你这样函数在render的时候已经执行了呀,肯定不行噻,
所以说要这样

onClick = {this.handleClick}

但是 这个函数 需要携带一个 i 的参数过去
所以 就要用一个匿名函数把i 带过去啊。。

onClick = {()=> this.handleClick(i)}

这样闭包 让 i 对 renderSquare 的i 保持引用

bind this 是另外一个问题吧 就像有一位老铁说的 xx = ()=> { 代码 } this就指向 当前 class,这个是class的类属性写法,需要 babel-plugin-transform-class-properties

不晓得我说对没有

...
onClick={这里是一个函数或函数引用}
onClick={() => this.handleClick(i)},这里面就是一个匿名函数,点击事件发生时,会执行这个匿名函数,匿名函数再调用handleClick函数(传参i);其次才是this绑定的问题

因为箭头函数不会绑定自己的this

如果不用箭头函数,需要手动绑定函数的thisonClick={() => this.handleClick.bind(this)(i)}

或者在定义的时候就用箭头函数:

handleClick = (i) => {
    //do it
}
onClick = {this.handleClick}

在使用ES6 classes或者纯函数时,React不会自动绑定this到当前组件上,需要手动实现this的绑定。

bind方法

<button onClick={this.handleClick.bind(this)}>Click</button>

构造器内声明

class Button extends React.Component{
  constructor(){
    this.handleClick=this.handleClick.bind(this);
  }
  render(){
    return <button onClick={this.handleClick}>Click</button>
  }
}

箭头函数

箭头函数可以自动绑定定义此函数作用的this,因此不需要bind

<button onClick={() => this.handleClick()}>Click</button>

看到这么多奇怪的评论忍不住注册个账号上来说两句。这几十个回复是怎么回事啊!不要误人子弟好不,跟this有半毛钱关系么???完全是为了传参好不!如果你不需要传参写onClick={this.funcName}不行的话你来找我!

会继承事件本身的this,还有一种写法: const handleClick = ()=>{.....},<button onClick = "this.
handleClick"></button>

使用箭头函数,能保证handleClick内的this指向当前组件对象,你的第二种写法,需要手动绑定this,不然handleClick内的this是不指向当前组件对象的。
我写过一篇React中如何进行事件处理的文章,你可以参考下:https://segmentfault.com/a/11...

新手上路,请多包涵

这里并不是为了绑定this,两种写法也并不等效。

myFunc = () => {
  alert("提示框");
}
...
onClick = () => this.myFunc();
//等价于
onClick = function() {
  return function myFunc() {
    alert("提示框");
  };
}


onClick = this.myFunc();
//等价于
onClick = function() {
   alert("提示框");
}

说匿名函数的才是对的。
第一种不会立即执行,点击才会执行。
第二种是匿名函数,是会立即执行的。

箭头函数可以解决this指向问题

我记得这个下棋的例子是官方demo
但是官方的文档里面,很多地方的事件绑定是在constructor里面用bind绑定的。

防止内部代码的this指的不是react实例。

箭头函数没有上下文的this指向

如果为了性能,不建议 <Square onClick={() => this.handleClick(i)} />,
建议 <Square i={i} onClick={this.handleClick} />,

箭头函数并不是没有 this,它的 this 是词法作用域,在函数定义的时候就确定了,而不是函数运行时决定
react onClick中的this与js原生的事件处理函数中的this一样若不做特殊处理大部分时间是指向 window 的。

要是你不传参可以不用箭头函数,要是你穿参数需要用箭头函数,不然函数立即执行了,onclick如何触发呢?不用箭头函数this没办法确定

React向事件处理程序传递参数示例:

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

上述两种方式是等价的,分别通过 arrow functions 和 Function.prototype.bind 来为特定事件类型添加事件处理程序。

参考官方翻译文档:React官方翻译文档
推荐问题
宣传栏