1 基本用法
在React中绑定事件跟直接在HTML中绑定事件非常相似,定义一个事件处理函数,并在JSX中绑定它:
function Greeting () {
function sayHi(e) {
e.preventDefault()
console.log('Hi!')
}
return (
<a onClick={Greeting}>Click me to say hi!</a>
)
}
所有事件绑定属性比如
onClick
均使用驼峰写法(camelCase),事件绑定属性的值不是字符串而是事件处理函数名称,可以带上()
并传参,无参数时可省略()
;2 使用类定义组件时事件处理函数
this
的指向问题使用ES6的
class
特性定义组件时,通常的做法是将事件处理函数当作该类的方法写在类中。但需要注意的是方法的this
指向。定义在类中的方法的默认的
this
指向的是当前的类的实例,但事件处理函数因为是绑定到了具体的元素上,就会丢失定义时this
的指向。如果你的处理函数中使用了this
关键字来指向当前组件实例,那么你需要手动将该方法的this
绑定到当前组件实例,有三种方法可以进行绑定:1)在类的constructor中调用或在JSX中调用
Function.prototype.bind()
手动绑定
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
this.handleClick = this.handleClick.bind(this); // 手动绑定
}
handleClick() {
// console.log(this)
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
render() {
return (
// <button onClick={this.handleClick.bind(this)}> // 在这里绑定也可以
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('content')
);
2)在JSX的事件绑定属性中的事件处理函数外层再套一个箭头函数,在其中返回处理函数调用结果
render() {
return (
<button onClick={(e) => this.handleClick(e)}> // 这么绑定也行
Click me
</button>
);
}
3)Babel提供的一个ES8+的实验性质的写法
class LoggingButton extends React.Component {
handleClick = () => { // 纯粹的实验性质的写法,需要babel的支持
console.log('this is:', this);
}
render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
}
3 事件对象
React的事件对象是一个完全由React给出的事件对象,该对象对各个浏览器做了兼容,同时保留了标准事件对象的接口,详细信息可以查看React官网的参考。使用时需要关心的是如何在事件处理函数中使用事件对象。
在事件绑定的JSX中,处理函数接受一个名为
event
的参数来表示事件对象,可以认为event
在事件绑定插值中属于React的保留字,如果需要往事件处理函数中传递更多参数,请使用其他标识符。另外,7.2小节中不同的事件绑定写法也对事件对象的处置略有不同,主要体现在事件绑定JSX中:
// 无括号
<button onClick={this.handleClick}>
Click me
</button>
// 带括号
<button onClick={this.handleClick(event)}>
Click me
</button>
// 调用了bind()
<button onClick={this.handleClick.bind(this, event)}>
Click me
</button>
- 当事件绑定插值中的处理函数省略了
()
时,处理函数默认接受一个表示事件对象的参数,- 当事件绑定插值中的处理函数未省略
()
时,则需要显示地使用保留字event
来传入事件对象,未传入则为undefined
;注意,不管有没有在constructor
中绑定this
,直接在处理函数名后加()
会导致页面初始化时该函数被立即执行一次,可能会有意想不到的错误,比如不能调用setState()
方法等,所以强烈不建议用这种写法- 当事件绑定插值中的处理函数调用了
bind()
时,可以显示地使用保留字event
来传入事件对象,否则React会在bind()
函数参数序列的末尾默认增加一个表示事件对象的参数最后,在React中不能通过
return false
来阻止默认事件,而是需要在事件处理函数中显式调用event.preventDefault()
。