1,使用
在 React 中绑定事件比较简单。来看下3种使用方式:
函数组件
export default function Button() {
function handleClick() {
alert('你点击了我!')
}
return <button onClick={handleClick}>点我</button>
}
或内联事件处理函数:
export default function Button() {
return (
<>
<button
onClick={function handleClick() {
alert('你点击了我!')
}}
>
点我
</button>
<button
onClick={() => {
alert('你点击了我2!')
}}
>
点我2
</button>
</>
)
}
类组件
import React, { Component } from 'react'
export default class Button extends Component {
handleClick() {
alert('你点击了我!')
}
render() {
return <button onClick={this.handleClick}>点我</button>
}
}
内联事件处理函数,写法一致。
2,注意事项
-
React 中内置的组件(HTML标签)的事件处理函数,仅支持浏览器事件名称。
换句话说,这些事件处理函数也算是标准的 DOM 属性,所以支持。 -
惯例的命名方式为【handle + 事件名】。比如
onClick={handleClick}
,onMouseEnter={handleMouseEnter}
等。
3,类组件 this 指向问题
在类组件中定义的事件处理函数,内部的 this
指向会有问题。没有做特殊处理的话,this
将指向 undefined
。
举例:
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
class Button extends Component {
handleClick() {
console.log('this-click', this) // undefined
}
render() {
console.log('this-render', this) // 组件实例
return (
<button onClick={this.handleClick}>点我</button>
)
}
}
ReactDOM.render(<Button />, document.getElementById('root'))
原理
在类中定义的方法是在原型上。默认情况下,在调用时没有指定 this
,那么方法内的 this
将被置为 undefined
(参考)。
不是全局对象 window 的原因是:class 体内部的代码总是在严格模式下执行。
所以,当作为事件处理函数调用时,onClick
对应的是一个回调函数,也就是 this.handleClick
是方法的引用,此时并没有指定 this
值,所以内部的 this
是 undefined
。
类似如下效果:
'use strict'
const obj = {
name: '下雪天的夏风',
foo: function () {
console.log(this.name)
}
}
const bar = obj.foo
bar() // Uncaught TypeError: Cannot read properties of undefined (reading 'name')
而 render
方法中,this
指向组件实例是因为:在ReactDOM.render
执行的时候,会new
一个实例对象来调用render
方法,实例直接调用时,this
自然指向实例自身。
解决
实现:事件处理函数的 this
指向实例对象。
1,bind
class Button extends Component {
constructor(props) {
super(props);
// this 就是实例对象
this.handleClick = this.handleClick.bind(this);
}
}
2,箭头函数
换句话说,箭头函数在定义时,this
的值已经确定了(会捕获其所在上下文的 this
值)。而不像普通函数那样在调用时才能决定 this
的指向。
箭头函数体中的 this
将正确指向实例。
class Button extends Component {
handleClick = () => {
console.log("this-click", this);
};
}
3,内联函数
class Button extends Component {
render() {
return (
<button
onClick={() => {
console.log("this-click", this);
}}
>
点我
</button>
);
}
}
以上。