前言
接下来让我们进入新的章节:漫谈React。
本篇文章主要讲React事件系统和表单操作。
正文
一:事件系统
1.react的事件系统
react事件系统符合W3school标准,不存在任何IE兼容性问题,并且与原生的浏览器事件一样有同样的API接口。同样支持事件的冒泡机制,我们可以使用stopPropagation()和preventDefault()来终止它。
所有的事件都自动绑定到最外层。如果需要访问原生事件对象,可以使用nativeEvent属性。
2.合成事件
(1)事件委派
react把所有事件绑定到结构的最外层,使用一个同意的事件监听器,这个事件监听器上维持了一个映射来保存所有组件内部的事件监听和处理函数。
(2)自动绑定
在react组件中,每个方法的上下文都会指向该组件的实例,即自动绑定this为当前组件。但是在使用ES6 classes或者纯函数时这种自动绑定就不复存在,需要手动实现this的绑定。
(3)绑定方法
3-1:bind方法:可以帮助我们绑定事件处理完器内的this,并且可以向事件处理器中传入参数,比如:
import React,{Component} from 'react'
class App extends Component{
handleClick(e,arg){
console.log(e,log);
}
render(){
return <button onClick={this.handleClick.bind(this,'test')}>Test</button>;
}
}
3-2构造器内声明(推荐):在组件的构造器内完成对事件的绑定。
class App extends Component{
handleClick(e){
console.log(e);
this.handleClick=this.handleClick.bind(this);
}
render(){
return <button onClick={this.handleClick.bind(this,'test')}>Test</button>;
}
}
3-3箭头函数:它自动绑定了定义此函数作用域的this。
class App extends Component{
const handleClick= (e)=>{
console.log(e);
}
render(){
return <button onClick={this.handleClick.bind(this,'test')}>Test</button>;
}
}或
import React,{Component} from 'react'
class App extends Component{
handleClick(e,arg){
console.log(e,log);
}
render(){
return <button onClick={()=>this.handleClick()}>Test</button>;
}
}
3.原生事件
componenDidMount会在组件已经完成安装并且在浏览器存在真实的 DOM后调用,此时我们就可以完成对原生事件的绑定。
import React,{Component} from 'react'
class nativeEventDemo extends Component{
componentDidMount(){
this.refs.button.addEventListener('click',e=>{
handleClick(e);
})
}
handleClick(e){
console.log(e);
}
componentWillUnmount(){
this.refs.button.removeEventListener('click');
}
render(){
return <button ref = 'button'>Test</button>
}
}
注意:在react中使用DOM原生事件时,一定要在组件卸载时手动移除,否则可能出现内存泄漏问题。
4.混合事件
我们无法在组件中将事件绑定到组件范围之外的区域,只能使用原生事件来实现。
但是,尽量在React中混用合成事件和原生DOM事件:用reactEvent.nativeEvent.stopPropagatoin()来阻止事件冒泡是不行的。组织React事件冒泡的行为只适用于React合成系统中,且没办法阻止原生事件冒泡。反之,在原生事件中阻止事件冒泡,却可以阻止React事件的传播。
对于无法使用React的合成事件系统的场景,我们还需要使用原生事件来完成。