五、事件处理
- 驼峰命名法
- React元素绑定事件要用{}包起来
在DOM事件中,处理函数返回false来阻止事件的默认行为,但在React事件中,必须显示调用对象的preventDefault方法来阻止事件的默认行为。如果必须使用DOM提供的原生事件,可以通过React事件对象的nativeEvent属性获取。
es6 class不会为方法自动绑定this到当前对象,React事件处理函数的写法主要有三种方式,不同的写法解决this指向问题的方式也不同。
- 使用箭头函数
import React, { Component } from "react";
class User extends Component {
constructor(props){
super(props);
this.state = {number: 0};
}
handleClick(e){
console.log(this.state.number);
}
render() {return (
<div>
<button onClick={(e) => {this.handleClick(e);}}>Click</button>
</div>
)
}
}
export default User;
存在问题:每次render调用时,都会重新创建一个新的事件处理函数,带来额外的性能开销。组件所在层级越低,开销越大。
- 使用组件方法
import React, { Component } from "react";
class User extends Component {
constructor(props){
super(props);
this.state = {number: 0};
this.handleClick = this.handleClick.bind(this);
}
handleClick(e){
console.log(this.state.number);
}
render() {return (
<div>
<button onClick={this.handleClick}>Click</button>
</div>
)
}
}
export default User;
存在问题:当有多个事件处理函数需要绑定时,代码显得繁琐。
也可以写成:
<button onClick={this.handleClick.bind(this)}>Click</button>
存在问题:每次render都会重新创建一个新函数,但在需要为处理函数传递额外参数时这种写法就有了用武之地。
<button onClick={this.handleClick.bind(this,item)}>Click</button>
- 属性初始化语法
使用es7的property initializers会自动为class中定义的方法绑定this。
import React, { Component } from "react";
class User extends Component {
constructor(props){
super(props);
this.state = {number: 0};
}
//es7的属性初始化语法,实际上也是使用了箭头函数
handleClick = (e) => {
console.log(this.state.number);
}
render() {
return (
<div>
<button onClick={this.handleClick}>Click</button>
</div>
)
}
}
export default User;
存在问题:处理试验阶段,默认不支持,不过使用官方脚手架Create React App创建的项目默认支持,也可以自行在项目中引入transform-class-properties插件获取支持。