事件处理
事件绑定的方式
事件监听
使用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>
} }