react笔记_08react中进行事件绑定

复习-原生js进行事件绑定

原生js具有三种事件绑定方式: 行内事件绑定、使用on关键字进行事件绑定、使用addEventListener方法进行事件绑定

行内事件绑定

语法

  <标签 onxxx='执行代码'></标签>
  • 当事件被触发时,就会执行引号间的代码
  • 举例说明1
      <div onclick="console.log('执行了')">点击</div>
    
    当点击该标签时就会在控制台打印-执行了
  • 举例说明2
    <div onclick="test1()">点击</div>
    <script>
     function test1(){
       console.log('执行了')
     }
    </script>
    
    点击该标签时就会在控制台打印-执行了

原理
当触发事件时就会执行绑定的代码!!!若你绑定的是一段逻辑代码,触发事件直接执行逻辑代码; 若是方法的调用,触发事件时是直接调用该事件函数,this指向window。

通过on关键字进行事件绑定

语法

dom.onxxx = 函数
  • 当事件被触发时,就会通过该dom元素调用绑定的方法
  • 举例说明
    <div id="test">点击</div>
    <script>
      function test(){
        console.log('执行了')
      }
      document.getElementById('test').onclick = test
    </script>
    

原理

当事件被触发时,就会通过该dom元素调用绑定的方法,方法内部的this指向为 dom元素

通过addEventListener方法进行事件绑定

语法

  dom.addEventListener(事件类型,方法名,bol)
  • 当事件被触发时,就会通过该dom元素调用绑定的方法
  • 举例说明
    <div id="test">点击</div>
    <script>
     function test(){
       console.log('执行了')
     }
     document.getElementById('test').addEventListener('click', test, false)
    </script>
    

原理
当事件被触发时,就会通过该dom元素调用绑定的方法,方法内部的this指向为 dom元素

react中进行事件绑定

在react中这三种方式均支持,但是为了减少dom操作,更推荐使用行内方式进行事件绑定

语法
<标签 onXxx='方法名'></标签> 
举例说明
 <div id="test"></div>
  <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script type="text/babel">
    class Test extends React.Component{
      render(){
        return <h1 onClick={this.test}>点击</h1>
      }
      test(){
        console.log('执行了')
      }
    }
    ReactDOM.render(<Test/>,document.getElementById('test'))
  </script>
与原生区别
  • 事件名
    • 原生为非驼峰命名(onxxx)
    • react为驼峰命名(onXxx)
    • 为什么react中事件绑定与原生js事件绑定不一致?
      • react并不是使用的原生DOM事件,而是在原生DOM事件基础之上封装了一层(onXxx是基于onxxx封装的)
        • 为了更好的兼容性
        • 为了更加高效–通过事件委托方式处理的(委托给组件最外层的元素)
  • 绑定的值
    • 原生为逻辑代码/方法的调用
    • react为 方法名
    • 为什么react绑定的是函数而不是函数调用->实现原理不同
      • 原生js是当事件被触发时 执行 对应的逻辑代码
        <div onclick="test1()">点击</div>
        <script>
          function test1(){
            console.log('执行了')
          }
        </script>
        
        当点击事件被触发时,执行引号间的代码-> 发现是函数调用-> 直接调用函数;
      • react在调用render函数时会获取到vdom,若是发现存在事件绑定,执行绑定的值
        return <h1 onClick={this.test}>点击</h1>
        test(){
          console.log('执行了')
        }
        </script>
        
        调用render函数时获取vdom,发现h1存在事件绑定-> 先执行代码this.test(函数体也是表达式,返回值为函数本身) -> 得到test函数;
        当事件被触发时,调用该函数;
        因此:当点击h1时会打印执行了;
         return <h1 onClick={this.test()}>点击</h1>
         test(){
           console.log('执行了')
         }
        </script>
        
        调用render函数时获取vdom,发现h1存在事件绑定-> 先执行代码this.test() -> 获取到的是undefined
        当事件被触发时,无函数可执行
        因此:一进入页面会打印执行了,当事件被触发时无任何变化;
    • 总结:
      • 原生js事件绑定的值只有在事件被触发时才会执行
      • react中的事件绑定 会在render函数调用时被触发,函数的返回值才是函数被触发时执行的逻辑代码
react事件的this指向
 <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
  class Mycomponent extends React.Component{
    render(){
      console.log(this) // 实例化对象
      return <h1 onClick={this.test}>测试事件绑定</h1>
    }
    test(){
      console.log(this) // undefined
    }
  }
  ReactDOM.render(<Mycomponent />, document.getElementById('test111'))
</script>
  • 事件绑定的函数的this指向的是undefiend
  • 原因:
    • 当事件触发时,react会在内部直接调用该函数
    • 因此this应该指向window;
    • 但是代码在进行编译之前会先通过babel进行编译(将jsx编译为js)
    • babel编译是处于严格模式下
    • 因此this指向为undefiend
  • 但是在函数中经常通过this指向获取某些数据,因此如果想要将this指改为实例化对象
    • 1.通过显示绑定-bind
      <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
      <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
      <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
      <script type="text/babel">
      class Mycomponent extends React.Component{
        constructor(props){
          super(props)
          // 此处this指向了实例化对象
          // 【1】 寻找test方法,在原型对象中找到test方法
         // 【2】通过bind将方法的this指向修改为实例化对象(注:原型对象上的test方法的this还是指向undefiend)
         // 【3】接收返回的方法并添加在实例化对象上
          this.test = this.test.bind(this)
        }
       render(){
         console.log(this) // 实例化对象
         return <h1 onClick={this.test}>测试事件绑定</h1>
       }
       test(){
         console.log(this) 
       }
      }
       ReactDOM.render(<Mycomponent />, document.getElementById('test111'))
      </script>
      
    • 2.通过箭头函数获取this指向(推荐)
      <script type="text/babel">
      class Mycomponent extends React.Component{
        render(){
          console.log(this) // 实例化对象
          return <h1 onClick={this.test}>测试事件绑定</h1>
        }
        // 箭头函数本身没有this指向会通过作用于链寻找上一级的this指向
        // 需要注意:通过赋值的方式的函数会添加在实例化对象上而不是原型对象上
        test=()=>{
          console.log(this) // 实例化对象
        }
      }
      ReactDOM.render(<Mycomponent />, document.getElementById('test111'))
    </script>
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值