【React】React绑定事件

一、前言

在React中,事件是组件与用户或其他组件通信的重要方式,例如:点击按钮、输入文本、拖动元素等。事件绑定是指将事件处理函数与组件的某个属性或元素关联起来,以便在事件发生时执行相应的逻辑。
React事件绑定有很多种方式,每种方式都有其优缺点,本文将介绍四种常用的事件绑定方法,并比较它们的区别和使用场景

二、React元素事件处理与DOM元素区别

  1. React事件绑定属性的命名采用驼峰式写法,而不是小写。例如:原生的事件全都是小写onclick,React里的事件是驼峰onClick
  2. 如果采用JSX的语法需要传入一个函数作为事件处理函数,而不是一个字符串(DOM元素的写法)
  3. React的事件并不是原生事件,而是合成事件
  4. 在React中另一个不同是你不能使用返回false的方法阻止默认行为,必须明确的使用e.preventDefault()

三、React绑定事件与HTML绑定事件写法区别

1、HTML通常写法

<button onclick="clickHandle()">提交</button>

<script>
function clickHandle(e){
    
    
	e.preventDefault();	//阻止默认事件
	//或者使用如下的写法
	return false;
}
</script>

2、React中写法

<button onClick={
    
    clickHandle}>提交</button>

<script>
function clickHandle(e){
    
    
	e.preventDefault();	//阻止默认事件,不能使用return false
}
</script>

四、React绑定事件的四种方式

  • 当使用ES6 class语法来定义一个组件的时候,事件处理器会成为类的一个方法
  • 必须谨慎对待JSX回调函数中的this,类的方法默认是不会绑定this的。如果你忘记绑定 this.handleClick 并把它传入 onClick, 当你调用这个函数的时候 this 的值会是 undefined。
  • 通常情况下,如果你没有在方法后面添加 () ,例如 onClick={this.handleClick},你应该为这个方法绑定 this。

1、直接在render()里写行内的箭头函数(不推荐)

在回调函数中使用箭头函数,直接在render()里写行内的箭头函数(不推荐),这种写法存在的问题就是:当每次执行render()的时候就会创建一个不同的回调函数。在大多数情况下,这是没有问题的。然而如果这个回调函数作为一个属性值传入低阶组件,这些组件可能会进行额外的重新渲染

import React, {
    
     Component } from 'react';
import ReactDOM from 'react-dom';

class Box extends Component {
    
    
  handleClick(e,val){
    
    
  	console.log(e,val);
  }
  render() {
    
    
    return (
      <button onClick={
    
    (e)=>this.handleClick(e,'aa')}>添加</button>
    );
  }
}

ReactDOM.render(
  <Box />,
  document.getElementById('root')
);

2、在组件内使用箭头函数定义一个方法(推荐)

使用属性初始化器来正确的绑定回调函数(推荐),在组件内使用箭头函数定义一个方法

优点: 简单易懂,不需要使用bind方法,可以避免每次渲染时创建新的函数实例。
缺点: 类成员函数语法需要在构造函数中进行支持。
适用场景: 适用于处理简单的事件逻辑,组件树比较浅。

import React, {
    
     Component } from 'react';
import ReactDOM from 'react-dom';

class Box extends Component {
    
    
	handleClick =(e)=>{
    
    
		console.log(e);
	}
	render() {
    
    
		return (
			<button onClick={
    
    this.handleClick}>添加</button>
		);
	}
}

ReactDOM.render(
  <Box />,
  document.getElementById('root')
);

3、在render()方法中,使用bind绑定this(不推荐)

在render()方法肿,使用bind绑定this(不推荐)。直接在组件定义一个非箭头函数的方法,然后再render里直接使用onClick={this.handleClick.bind(this)}

优点: 代码简单易懂,容易理解。
缺点: 每次渲染都会创建一个新的函数实例,可能会影响性能。
适用场景: 适用于处理简单的事件逻辑,组件树比较浅,需要绑定this。

import React, {
    
     Component } from 'react';
import ReactDOM from 'react-dom';

class Box extends Component {
    
    
	handleClick(val,e) {
    
    	//事件对象e要放在最后
		console.log(val,e);
	}
	render() {
    
    
		return (
			<button onClick={
    
    this.handleClick.bind(this, 'aa')}>添加</button>
		);
	}
}

ReactDOM.render(
  <Box />,
  document.getElementById('root')
);

4、在constructor里bind(this)(推荐)

直接在组件内定义一个非箭头函数的方法,然后再constructor里bind(this)(推荐)

优点: 避免在每次渲染时都创建一个新的函数实例,提高性能。
缺点: 代码比较繁琐。
适用场景: 适用于处理复杂的事件逻辑,需要绑定this。

import React, {
    
     Component } from 'react';
import ReactDOM from 'react-dom';

class Box extends Component {
    
    
	constructor(){
    
    
		super();
		this.myhandleClick = this.handleClick.bind(this);
	}
	handleClick(e){
    
    
		console.log(e);
	}
	render() {
    
    
		return (
			<button onClick={
    
    this.myhandleClick}>添加</button>
		);
	}
}

ReactDOM.render(
  <Box />,
  document.getElementById('root')
);

五、React事件传参

1、使用方式一、方式三传递参数

和普通浏览器一样,事件 handleClick 会被自动传入一个 event 对象,这个对象和普通的浏览器 event 对象所包含的方法和属性都基本一致。不同的是 React中的 event 对象并不是浏览器提供的,而是它自己内部所构建的。它同样具有event.stopPropagation、event.preventDefault 这种常用的方法。

<button onClick={
    
    (e)=>this.handleClick(e, 'aa')}>添加</button>
<button onClick={
    
    this.handleClick.bind(this, 'aa')}>添加</button>

值得注意的是,通过 bind 方式向监听函数传参,在类组件中定义的监听函数,事件对象 e 要排在所传递参数的后面。

2、子组件中修改参数

在子组件中修改父组件传过来的参数,比较推荐的方法是, 在父组件中定义方法,子组件中调用父组件的方法,通过props传递到子组件中,然后在子组件中通过this.props.method来调用。看下面的例子:

①、子组件

class Button extends Component {
    
    
  handleClick(){
    
    
  	//执行DOM元素的 change属性
    this.props.change();
  }
  render() {
    
    
    return (
     <button onClick={
    
    ()=>this.handleClick()}>
       {
    
    this.props.children}
     </button>
    );
  }
}

②、父组件

class Counter extends Component {
    
    
  constructor() {
    
    
    super();
    this.state = {
    
    
      count: 0
    }
  }
  handleChange(type) {
    
    
    this.setState((preState, props) => {
    
    
          count: preState.count + 1
      } 
    }, () => {
    
     })
  }

  render() {
    
    
    return (
      <div >
        <Button change={
    
    () => this.handleChange()}>-</Button>
      </div>
    );
  }
}

六、总结

React中的事件绑定提供了多种选择,使开发人员能够选择最适合他们的方式。使用addEventListener方法、React事件系统或第三方库,都可以实现事件绑定。选择哪种方式取决于开发者的个人偏好和项目需求。

猜你喜欢

转载自blog.csdn.net/weixin_45490023/article/details/133267858