监听事件只需要给需要监听事件的元素加上属性类似于 onClick、onKeyDown 这样的属性。
我们现在要给 Title 加上点击的事件监听
class Title extends Component {
handleClickOnTitle () {
console.log('click on title')
}
render () {
return (
<h1 onClick = {this.handleClickOnTitle}>React 小书</h1>
)
}
}
只需要给 h1 标签加上 onClick 的事件,onClick 紧跟着是一个表达式插入,这个表达式返回一个 Title 自己的一个实例方法。当用户点击 h1 的时候,React.js 就会调用这个方法.
没有经过特殊处理的话,这些 on~ 的事件监听只能用在普通的 HTML 的标签上,而不能用在组件标签上。也就是说,<Header onClick={…} /> 这样的写法不会有什么效果的。
event对象
这次尝试当用户点击 h1 的时候,把 h1 的 innerHTML 打印出来:
class Title extends Component {
handleClickOnTitle (e) {
console.log(e.target.innerHTML)
}
render () {
return (
<h1 onClick = {this.handleClickOnTitle}>React 小书</h1>
)
}
}
和普通浏览器一样,事件监听函数会被自动传入一个
event
对象,这个对象和普通的浏览器 event
对象所包含的方法和属性都基本一致。不同的是 React.js 中的 event
对象并不是浏览器提供的,而是它自己内部所构建的。React.js 将浏览器原生的 event
对象封装了一下,对外提供统一的 API 和属性,这样你就不用考虑不同浏览器的兼容性问题。这个 event
对象是符合 W3C 标准的,它具有类似于event.stopPropagation
、event.preventDefault
这种常用的方法。
This
一般在某个类的实例方法里面的 this 指的是这个实例本身。但是在上面的 handleClickOnTitle 中把 this 打印出来,会看到 this 是 undefined。
这是因为 React.js 调用你所传给它的方法的时候,并不是通过对象方法的方式调用(this.handleClickOnTitle),而是直接通过函数调用 (handleClickOnTitle),所以事件监听函数内并不能通过 this 获取到实例。
如果想在事件函数当中使用当前的实例,就需要手动地将实例方法 bind 到当前实例上再传入给 React.js。
class Title extends Component {
handleClickOnTitle (e) {
console.log('click on title')
console.log(e.target.innerHTML)
console.log(this)
}
render () {
return (
<h1 onClick = {this.handleClickOnTitle.bind(this)}>React 小书</h1>
)
}
}
bind 会把实例方法绑定到当前实例上,然后我们再把绑定后的函数传给 React.js 的 onClick 事件监听。这时候点击 h1 的时候,就会把当前的实例打印出来:
总结
为 React 的组件添加事件监听是很简单的事情,你只需要使用 React.js 提供了一系列的 on* 方法即可。
React.js 会给每个事件监听传入一个 event 对象,这个对象提供的功能和浏览器提供的功能一致,而且它是兼容所有浏览器的。
React.js 的事件监听方法需要手动 bind 到当前实例,这种模式在 React.js 中非常常用。