React中事件的处理
React 中使用 onClick 类似的写法来监听事件,注意 this 绑定问题 React 里严格遵循单项数据流,没有数据双向绑定,所以要处理两件事,第一是元素本身值的赋值,第二是值改变以后的事件,例如输入框需要设置 value 和 onChange 。
importReact,{ Component }from"react";
export default classCardSampleextendsComponent {
//状态的初始化一般放在构造器中
constructor(props) {
super(props);
this.state= {
text:'',
goods: []
}
//为了在回调中使用'this',这个绑定式必不可少的
this.textChange=this.textChange.bind(this);
}
//当input的值text发生变化的时候,调用textChange去切换input的值
textChange(event) {
this.setState({
text: event.target.value
})
}
addGoods= ()=> {
this.setState(prevstate => {
// prevstate.goods.push({
// id: prevstate.goods.length + 1,
// name: prevstate.text
// })
// react官方希望传入与返回的对象不应该是同一个对象,所以上面的写法需要改进
return{
goods: [
...prevstate.goods,//获取原来的商品填充到新的数组goods中
{
id: prevstate.goods.length+1,
name: prevstate.text
}
]
}
})
}
render() {
return(
<div>
{/*事件处理*/}
<div>
<inputtype='text'value={this.state.text}onChange={this.textChange}/>
<buttononClick={this.addGoods}>添加商品</button>
</div>
<ul>
{
this.state.goods.map((good)=>
return<likey={ good.id}>{ good.name}</li>
)
}
</ul>
</div>
)
}
}
注意:
- React 事件的命名采用小驼峰式(camelCase),而不是纯小写。且事件名称之后不能加 (),否则会直接执行
- 不能通过返回 false 的方式阻止默认行为。必须显式的使用 preventDefault
- 必须谨慎对待JSX回调函数中的this,在JavaScript中,class(类)的方法默认不会绑定this。如果忘记绑定this.textChange并把它传入了onChange,当调用这个函数的时候this的值为undefined。如果觉得使用bind麻烦,还可以使用箭头函数。
一、React组件中的事件处理函数
1、constructor函数中bind
classReactEventextendsComponent {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log('Click');
}
render() {
return <buttononClick={this.handleClick}>Click Me</button>;
}
}
2、使用箭头函数
(1)render中使用箭头函数
classReactEventextendsComponent {
handleClick() {
console.log('Click');
}
render() {
return <buttononClick={()=>this.handleClick()}>Click Me</button>;
} }
(2)使用class fields语法
classReactEventextendsComponent {
//此函数会被绑定到ReactEvent类的实例
handleClick = () => {
console.log('Click');
}
render() {
return <buttononClick={this.handleClick}>Click Me</button>;
} }
(3)在render中使用bind
classReactEventextendsComponent {
handleClick() {
console.log('Click');
}
render() {
return <buttononClick={this.handleClick.bind(this)}>Click Me</button>;
} }
二、几种方式比较
影响 | constructor函数中bind | 使用class fields语法 | render中使用箭头函数 | 在render中使用bind |
render时生成新函数 | 否 | 否 | 是 | 是 |
性能 | 无影响 | 无影响 | 有影响 | 有影响 |
可直接携带参数 | 否 | 否 | 是 | 是 |
简洁性 | 不好 | 好 | 好 | 好 |
三、事件处理中传参
在开发当中,经常遇到对一个列表做操作,可能包含删除,修改,查看。这时候绑定事件就需要传参,通常为id。
1、直接传递参数
2、使用data属性
例如:
importReact,{ Component }from"react";
export default classEventComponetextendsComponent {
constructor(props) {
super(props);
this.state= {
list: [
{
id:1,
msg:'AAA'
},
{
id:2,
msg:'BBB'
},
{
id:3,
msg:'CCC'
}
]
}
}
handleClick(e) {
console.log(e.target.dataset.id)
}
render() {
const{ list } =this.state
return(
<div>
{
list.map(item=><buttondata-id={ item.id}key={ item.id}onClick={this.handleClick}>{item.msg}</button>)
}
</div>
)
}
}
这里不强制推荐使用哪一种,对于各个团队来说,可以根据项目,选择自己团队的事件绑定方式。
因为箭头函数的简洁性,在公司项目中,通常使用class fields 定义箭头函数来绑定事件。当需要传参的时,单个参数传递使用data属性传参。多个参数传递时,采用拆分子组件的方式回调传参。