第六节:事件处理

100 阅读3分钟

事件处理

事件绑定的方式

事件监听

使用React时,不需要使用addEventListener为已创建的DOM元素添加监听器

React元素的事件处理与DOM元素很相似,只是存在一些语法上的差异:

  • React事件的命名采用小驼峰式,而不是纯小写
  • 使用JSX语法时,需要传入一个函数作为事件处理函数,而不是字符串

例如:

HTML中
<button onclick="handleClick()">点我一下试试</button>
在React// 1.使用 onClick 代替 onclick 
// 2.使用 {handleClick} 传入一个函数,而非字符串
<button onClick={handleClick}>点我一下试试</button>
ReactDOM.render(
<button onClick={handleClick()}>点我一下试试</button>, 
document.getElementById("app") )

函数不能触发的原因:{}中的代码为JS的表达式,会被立即解析

  • 示例中,会先解析handleClick(),会自执行一次handleClick;
  • 并且会将handleClick函数的返回值赋值给onClick,此处为undefined

class组件中的事件处理函数

为了保证组件的完整性、相对独立性,通常的做法是将事件处理函数声明为class中的方法

方法一:在constructor中将事件处理函数定义为组件实例的私有方法

class App extends React.Component {
constructor(){
super(); 
this.handleClick = function() { alert("试试就试试");
}     
}     
render(){
return <button onClick={this.handleClick}>点我一下试试</button>     
} }

方法二:使用class属性定义事件处理函数,与方法一的作用相同,会成为组件实例的私有方法

class App extends React.Component { 
handleClick = function() {
alert("试试就试试"); 
}
render(){
return <button onClick={this.handleClick}>点我一下试试</button> 
} }

方法三:将事件处理函数定义为组件的公有方法

class App extends React.Component {
// 注意与方法二的区别
handleClick() {
alert("试试就试试");
} 
render(){
return <button onClick={this.handleClick}>点我一下试试</button> 
} }

回调函数的this问题

由于是JavaScript函数语法的关系,JSX中回调函数的作用域是NULL,因此通常都是需要手动绑定this指向 以组件的事件处理函数为例:

  • constructor函数中绑定this

class App extends React.Component {
    constructor(){
        super();
        this.handleClick = this.handleClick.bind(this);
    }
    
    handleClick = function() { alert("试试就试试"); }
    render(){
        return <button onClick={this.handleClick}>点我一下试试</button>
    }
}
  • render函数中绑定this
class App extends React.Component {
handleClick = function() {
alert("试试就试试");
}
render(){
return <button onClick={this.handleClick.bind(this)}>点我一下试试</button> 
} }
  • 结合class属性与箭头函数
class App extends React.Component {
handleClick = () => {
alert("试试就试试"); 
}
render(){
return <button onClick={this.handleClick}>点我一下试试</button> 
} }

由于箭头函数中的this会指向父级上下文,而无需手动绑定,简洁高效,比较推荐使用。

向事件处理程序传递参数

传递参数的方式

  • 使用bind预传参
<button onClick={this.handleClick.bind(this, id)}>点我呀</button>
  • 在箭头函数外部嵌套一层函数
<button onClick={(e) => this.handleClick(id, e)}>点我呀</button>

React的事件对象

示例代码:

class App extends React.Component {
handleClick = (e) => {
console.log(e); 
}
render() {
return <button onClick={this.handleClick}>点我呀</button>     
}}

合成事件对象SyntheticEvent

为了解决跨浏览器兼容性问题,React将浏览器的原生事件封装为合成事件SyntheticEvent,并将它的实例作为事件对象(e)传入设置的事件处理程序。SyntheticEvent是React根据W3C规范的,是跨浏览器事件的包装器,与习惯的原生事件具有相同的接口。

阻止默认行为的差异

在React中,不能通过返回false的方式阻止默认行为,必须显式的使用precentDefault 例如,传统的HTML中阻止链接默认打开一个新页面可以为

<a href="https://www.w3cschool.cn/" onclick="return false">w3cschool</a>

但在React中需要这样:

class App extends React.Component {
handleClick = (e) => {
e.preventDefault() 
}  
        
        render() {
        return <a href="https://www.w3cschool.cn/" onClick={this.handleClick}>w3cschool</a>    
        } }