React事件处理
React事件处理是通过将事件处理器绑定到组建上处理事件,事件触发的同时更新组建的内部状态,内部状态更新会触发组件的重绘
React 元素的事件处理和 DOM 元素的事件处理很相似,但语法上的略有区别
- 在React中事件的命名采用驼峰命名法,即事件名的首字母为大写,而不是原生DOM中的小写
- 响应事件的函数要以对象的形式赋值,而不是以DOM字符串的形式
React方式
<button onClick={clickMe()}>提交</button>
DOM方式 <button onclick='clickMe()'>提交</button> dom方式
React中事件处理函数
在React中事件处理函数主要有三种写法,不同的写法this指向问题也不同,性能也有所差异
- ES6箭头函数
箭头函数适用于逻辑简单的事件,若逻辑复杂会导致render变得复杂,看不清UI的结构,代码可读性差
<script type="text/babel">
class Value extends React.Component{
constructor(props){
super(props);
this.state = {
value:1
}
}
render(){
return(
<div>
<button onClick={(event)=>{console.log(this.state.value)}}>Click Me</button>
</div>
)
}
}
ReactDOM.render(<Value/>,document.getElementById('text'));
</script>
按钮中绑定click事件里的this始终指向当前组件Value的实例
- 组件中定义事件函数
因为在自定义函数中this为null,若要在自定义函数中使用this,就必须进行绑定(将this强制绑定到自定义函数中)
<div id="text"></div>
<script type="text/babel">
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
number: 0
}
this.handelClick = this.handelClick.bind(this)
}
handelClick(){
this.state.number++;
console.log(this.state.number)
}
render(){
return (
<div>
<button type='button' onClick={ this.handelClick }>点我</button>
</div>
)
}
}
ReactDOM.render(<MyComponent />, document.getElementById('text'))
</script>
这种方法的好处是每次render渲染都不会重新创建一个回调函数,没有额外的性能损失,但是如果在一个组件中有很多的事件函数时这种在构造函数中绑定this的方法会显得繁琐
- 在事件赋值时绑定this
这个方法在每次render时都会重新创建一个新的函数,性能会有一定的损失,但在事件处理函数需要传参数时,这种方法就比较好
<div id="text"></div>
<script type="text/babel">
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
number: 0
}
}
handelClick(){
++this.state.number;
console.log(this.state.number)
}
render(){
return (
<div>
<button type='button' onClick={ this.handelClick.bind(this) }>点我</button>
</div>
)
}
}
ReactDOM.render(<MyComponent />, document.getElementById('text'))
</script>
关于this的绑定 在箭头函数中this指针指向组件的实例对象 不需要进行this绑定 在非箭头函数中若要使用this都必须进行绑定
事件流
react默认的事件流方式:冒泡
<div id="app"></div>
<script type="text/babel">
const style = {
child: {
width: '100px',
height: '100px',
backgroundColor: 'red'
},
parent: {
width: '150px',
height: '150px',
backgroundColor: '#bfa'
},
ancestor: {
width: '200px',
height: '200px',
backgroundColor: 'green'
}
}
class App extends React.Component{
render(){
return(
<div onClick={()=>console.log('ancestor')} style={style.ancestor}>
<div onClick={()=>console.log('parent')} style={style.parent}>
<div onClick={()=>console.log('child')} style={style.child}>
</div>
</div>
</div>
)
}
}
ReactDOM.render(<App />,document.getElementById('app'));
当点击红色区域也就是child 控制台输出依此是 若将事件的触发改为捕获方式,在事件后加Capture即可,若想阻止事件冒泡可以利用事件对象的stopPropagation()方法取消事件冒泡
<div onClick={(e)=>{
console.log('child');
e.stopPropagation();
}}
style={style.child}>
</div>
此时点击红色区域后控制台只输出child说明阻止冒泡成功
|