如何注册事件
驼峰命名法,语法
on+事件名={事件处理程序}
比如
onClick={this.buttonClick}
class App extends React.Component {
render() {
return (
<div>
<button onClick={this.buttonClick}>点击按钮触发事件</button>
</div>
)
}
buttonClick() {
alert('事件触发')
}
}
事件对象 (涉及阻止事件流 e.preventDefault())
通过事件处理程序的参数获取到
事件对象
function buttonClick(e) {
e.preventDefault()
console.log('事件对象', e)
}
// 比如阻止a标签调整的共呢个
<a onClick={this.buttonClick}>点击不调整,按钮样式</a>
this指向
关于React的this的指向,与我们JS的this指向原理是一致的,但为什么会丢失呢?这个是JS原本的缺陷。
this的指向坚持谁调用指向谁,我们可以通过react的源码看到render函数通过instance去调用的,那render内部的this指向肯定是instance;
如果我们在render函数内直接调用其他事件,它this的指向也会是instance;
如果我们在render return的虚拟dom的on事件当中注册事件的话,那this的指向会是undefined,因为是模块化环境,全局状态的this不是window而是undefined
那么为什么在vue框架里面不存在这个问题的呢?
vue实例里,我们所有方法都写在methods里面,我们通过源码可以发现,vue内部通过fn.bind(this),把所以方法的this都进行了绑定。
模块化环境下,非render方法调用、通过on注册事件(无论组件内外)中的this指向的是
undefined
【事件处理函数中】模块化环境下,render方法中的this指向是当前instance
this指向解决方案(建议使用方案3)
- 方案1:通过在render函数内调用去注册事件,结合箭头函数
class App extends React.Component {
state = {
title: 'hello react'
}
buttonClick() {
console.log(this.state.title)
}
render() {
return (
<div>
<button onClick={() => {this.buttonClick()}}>
点击按钮,查看this指向
</button>
</div>
)
}
}
- 方案2:使用bind绑定当前this(不调用fn),不要用apply、call,因为它们会调用fn
class App extends React.Component {
state = {
title: 'hello react'
}
buttonClick() {
console.log(this.state.title)
}
render() {
return (
<div>
<button onClick={this.buttonClick.bind(this)}>
点击按钮,查看this指向
</button>
</div>
)
}
}
- 方案3:声明方法的时候使用箭头函数,箭头函数没有自己的this,声明时就指向当前环境的this,就是instance
class App extends React.Component {
state = {
title: 'hello react'
}
buttonClick = () => {
console.log(this.state.title)
}
render() {
return (
<div>
<button onClick={this.buttonClick}>
点击按钮,查看this指向
</button>
</div>
)
}
}