持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第12天,点击查看活动详情
学习react已经有段时间了,现在开始实战巩固。 记录一些遇到的坑!
坑:React的点击事件问题
在vue中的点击事件,就是给标签绑上点击事件之后,vue2在methods里写方法,vue3则是在setup中写方法。React的操作类似,但类式组件会多一步,就this的指向问题。
举例来说:
class A extends React.Component{
constructor(props){
super(props);
this.state = {
a: props.value
}
this.handleClick = this.handleClick.bind(this) //通过bind获取this
}
handleClick(e){
conole.log(e)
}
render(){
return(
<div onClick={this.handleClick}></div>
)
}
}
从上面的例子,可以看到在写handleClick()这个方法之前,先通过了bind获取到了this。然后点击一下div,就能获取到this。
那么如果我不绑定this呢?
可以看到此时的this为undefined,为什么呢?
原因是class式组件默认是不会绑定this的,如果没有绑定this,那么当函数调用this时,它的值就为undefined。
绑定this的几种方法
1、利用bind更改this的指向,就是上面例子的写法,但这种比较麻烦一些。 2、优化方法一的写法,在点击时使用bind更改this指向。
class TabBar extends React.Component {
constructor(props) {
super(props);
this.state = {
key: 0,
tabName: props.tabName
}
// this.handleClick = this.handleClick.bind(this);
}
handleClick(e,index) {
console.log(this,'绑定了this');
console.log(index);
this.setState({
key: e
})
}
render() {
const listName = this.state.tabName.map((i,index) => <span onClick={this.handleClick.bind(this,index)} className={['tabs',index===this.state.key?'hovers':''].join(' ')} key={i}>{i}</span>)
return (
<div className="App-header">
<div className='tabBar'>
<div className='tabName'>{listName}</div>
</div>
</div>
);
}
}
3、回调函数
<div onClick={e=>this.handleClicks(e)} className='tabName'>{listName}</div>
4、箭头函数,这是比较好的一个写法
handleClicks = ()=>{
console.log(this)
}
<div onClick={this.handleClicks} className='tabName'>{listName}</div>
那么想携带参数时,怎么办?天真的我觉得不就是this.handleClick(val)不就可以了吗?但是出错了。 我采用第一种方法,然后传递参数,结果出现了问题,通过百度大法后,我大致了解到了,react带参数传值有两种写法: 1、在点击时使用bind方法传值
handleClicks (val){
console.log(val)
}
<div onClick={this.handleClicks.bind(this,'传值')} className='tabName'>{listName}</div>
2、利用回调函数传递参数
handleClicks (val,e){
console.log(val)
}
<div onClick={e=>this.handleClicks.bind('传值',e)} className='tabName'>{listName}</div>
也可用箭头函数的写法
handleClicks =(val,e)=>{
console.log(val)
}
<div onClick={e=>this.handleClicks.bind('传值',e)} className='tabName'>{listName}</div>