React是怎么进行事件处理的

2024-06-26 1303阅读

什么是事件?

事件是指一些可以通过脚本响应的页面动作。当用户按下鼠标或者提交一个表单等等时候,事件都会出现。事件处理是一段JavaScript代码,总是与页面中的特定部分以及一定的事件相关联。当与页面特定部分相关联的事件发生时,事件处理器就会被调用。

JavaScript常用事件

React是怎么进行事件处理的

React的事件处理

React 元素的事件处理和 DOM 元素的很相似。但是React的两点最大的不同是

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

阻止默认行为

注意: 在 React 中另一个不同点是你不能通过返回 false 的方式阻止默认行为。你必须显式的使用 preventDefault

代码示例:

原生写法:


  Click me

我们返回了false后会阻止标签的原始跳转功能。只执行我们的console.log

React写法:

    function ActionLink() {
      function handleClick(e) {    e.preventDefault();    console.log('The link was clicked.');  }
      return (
        handleClick}      Click me
        
      );

功能上是和上面的代码一样的。但是在这里,e 是一个合成事件。React 根据 W3C 规范来定义这些合成事件,所以你不需要担心跨浏览器的兼容性问题。

为DOM元添加监听器

React不需要使用 addEventListener 为已创建的 DOM 元素添加监听器。只需要在该元素初始渲染的时候添加监听器即可。

代码示例:

    定义一个Toggle组件,当我们点击按钮时会切换我们按钮中的值,一直在NO和OFF中切换。
    class Toggle extends React.Component {
      constructor(props) {
        super(props);
        this.state = {isToggleOn: true};
        // 为了在回调中使用 `this`,这个绑定是必不可少的   
        this.handleClick = this.handleClick.bind(this);  
        }
            执行我们的切换事件,切换state值
      handleClick() {  
          this.setState(state => ({ 
          进行取反
          isToggleOn: !state.isToggleOn    
          })); 
          }
          
      render() {
        return (
          this.handleClick}      
          {this.state.isToggleOn ? 'ON' : 'OFF'}
          
        );
      }
    }
    ReactDOM.render(
      ,
      document.getElementById('root')
    );

注意: 我们必须谨慎对待 JSX 回调函数中的 this,因为在 JavaScript 中,class 的方法默认不会绑定 this。如果你忘记绑定 this.handleClick 并把它传入了 onClick,当你调用这个函数的时候 this 的值为 undefined。因为this 本质上就是指向它的调用者,this 是在函数运行时才绑定,在JavaScript 中普通函数都是 window 调用的,所以指向 window但是我们的JSX 语法是不被 webpack 识别的,webpack 默认只能处理 .js 后缀名的文件,所以需要借助 Babel 这个 JavaScript 编译器,而 babel 开启了严格模式 ,开启了严格模式下无法再意外创建全局变量。所以this指向的是 undefined。

解决React组件this指向问题的两种方法

方法一、在构造函数中使用bing

    class index extends Component {
        constructor(){
            super()
            this.speak = this.speak.bind(this)
            /*解决类中的this问题:this.speak = this.speak.bind(this),构造器里面的this默认指向实例对象,
          实例对象通过原型链在类的原型上找着fnc函数,通过bind函数将其this指向改为实例对象,并返回一个新的函数
          再将这个新的函数给实例,并取名为fnc*/
        }
        speak(){
            console.log(this)//输出当前实例对象
        }
        render() {
            return (
                
this.speak}按钮
) } }

为什么是bind呢?

众所周知call、apply、bind 都可以改变我们的this指向。那为什么是bind呢?

区别:

  • call 和 bind 可以直接接受多个参数 apply 则是将参数放进一个数组
  • call 和 apply 返回立即执行函数,bind 返回新的函数,bind()() 也是立即执行
  • call和apply都是临时改变一次this指向,并立即执行。而bind是返回一个永久改变this指向的函数。使用 bind 绑定 this 后,该函数里面的 this 不能变化了,不论是谁调用

    方法二、将箭头函数赋值给类的属性

        class index extends Component { 
            speak = () =>{ 
                console.log(this)
         } 
             render() { 
                 return ( 
                     
    this.speak}按钮
    ) } }//需要传参的话,可以使用函数柯里化的思想

    为什么什么箭头函数没影响呢?

    箭头函数:箭头函数并不会创建自己的执行上下文,所以箭头函数中的this都是外层的this,会向外作用域中,一层层查找this,直到有 this 的定义

    注意:性能存在差异

    使用箭头函数来解决性能会比较低,因为箭头函数不是方法,它们是匿名函数表达式,所以将它们添加到类中的唯一方法是赋值给属性。前面介绍ES6的类的时候可以看出来,ES 类以完全不同的方式处理方法和属性

    方法被添加到类的原型中,而不是每个实例定义一次。

    类属性语法是为相同的属性分配给每一个实例的语法糖,实际上会在 constructor里面这样实现:

        constructor(){
            super()
            this.speak = () => {console.log(this)}
        }
    

    这意味着新实例被创建时,函数就会被重新定义,丢失了JS实例共享原型方法的优势。而方法一,只是在生成实例时多了一步 bind 操作,在效率与内存占用上都有极大的优势

    向事件处理程序传递参数

    在循环中,通常我们会为事件处理函数传递额外的参数。例如,若 id 是你要删除那一行的 ID,以下两种方式都可以向事件处理函数传递参数:

        (e) = this.deleteRow(id, e)}>Delete Row
        //推荐第二种
        this.deleteRow.bind(this, id)}Delete Row
    

    在这两种情况下,React 的事件对象 e 会被作为第二个参数传递。如果通过箭头函数的方式,事件对象必须显式的进行传递,而通过 bind 的方式,事件对象以及更多的参数将会被隐式的进行传递。

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]