问题描述
- 当使用
<button onClick={this.onClickButton}>Click Me</button>
时工作正常; - 而使用
<button onClick={this.onClickButton(param)}>Click Me</button>
时,每次函数都会自动被调用。
首先摘抄某博客中的内容:
One way of accessing the properties of an object is via the dot operator (.). This operator has two different modes:
- Getting and setting properties: obj.prop
- Calling methods: obj.prop(x, y)
The latter is equivalent to:
obj.prop.call(obj, x, y)
所以<button onClick={this.onClickButton}>Click Me</button>
可以直接把this.onClickButton
写在括号内,因为这样用的是第一种方法,实际上是将onClickButton
作为一个属性传给onClick
,调用onClick
后才执行该函数,也就相当于:
const onClick = this.onClickButton
onClick();
这时onClick
中会有一个隐含的this
参数,使函数内部不能通过this
读取到外层组件,因此需要在外部组件的constructor
中添加this.onClickButton = this.onClickButton.bind(this)
,将外部组件的this
传入函数内部。
相反,<button onClick={this.onClickButton(param)}>Click Me</button>
中使用的是上述第二种带括号的,实际加载时,先调用onClickButton(param)
函数,然后将其返回值赋给onClick
。因此每次加载时组件会自动调用onClickButton
函数,而在constructor
中也不用将this
绑定给onClickButton
。
解决方法
使用匿名函数,<button onClick={()=>this.onClickButton(param)}>Click Me</button>
,直接将该匿名函数作为一个整体赋值给onClick
,当onClick
被调用时,该匿名函数才被执行。又由于箭头函数不会将函数内部的this
覆盖(原理可读上述博客),因此在函数内部仍然可以读取到外部组件的this
,从而在这种情况下也不需要在constructor
中把this
绑定给onClickButton
。