react笔记_06react中进行事件绑定_乖女子@@@的博客-爱代码爱编程
复习
原生js进行事件绑定
使用原生js事件绑定的三种方式 行内事件绑定、使用on进行事件绑定、使用addEventListener进行事件绑定
- [1]在行内进行事件绑定:在行内通过 onxxx=‘方法名()’ 进行事件绑定;
- [2]通过on关键字进行事件绑定:通过 dom.onxxx= function(){ } 进行事件绑定
- [3]通过addEventListener方法进行事件绑定 :通过 dom.addEventListener(事件类型,方法名,bol)
当事件被触发时就会执行对应的方法
举例说明
需求:默认显示文本 今天天气炎热,当点击文本时显示 今天天气凉爽
- 实现1:在行内进行事件绑定
通过行内进行事件绑定,触发事件时是自动调用
的事件函数,this指向window
<div id="test" onclick="toedittext()">今天天气炎热</div> <script> function toedittext(){ const content = document.getElementById('test').innerHTML document.getElementById('test').innerHTML= content=='今天天气炎热' ? '今天天气寒冷' : '今天天气炎热' console.log(this) // window } </script>
- 实现2:通过on关键字进行事件绑定
document.getElementById('test2').onclick = function(){ const content = document.getElementById('test2').innerHTML document.getElementById('test2').innerHTML= content=='今天天气炎热' ? '今天 天气寒冷' : '今天天气炎热' console.log(this) // dom元素 }
- 实现3:
// [3] 通过addEventListener来进行事件绑定 document.getElementById('test3').addEventListener('click', function(){ const content = document.getElementById('test3').innerHTML document.getElementById('test3').innerHTML= content=='今天天气炎热' ? '今天天气寒冷' : '今天天气炎热' console.log(this) // dom元素 },false)
总结this指向
使用行内方式进行事件绑定,在事件被触发时是直接调用
,因此方法内的this指向为Window
;
在使用关键字或方法进行事件绑定,在事件被触发时是通过dom元素调用,因此方法内部的this指向为 dom元素
react中进行事件绑定
在react中这三种方式均支持,但是为了减少dom操作,更推荐使用行内方式
进行事件绑定
语法
在行内通过 onXxx='方法名' 进行事件绑定
- 与原生区别:
- 事件名
- react为驼峰命名(onXxx)
- 原生为小写(onxxx)
- 绑定的值
- react为方法名
- 原生为方法的调用
- 为什么react中事件绑定与原生js事件绑定不一致?
- 不使用onxxx而用onXxx
- React使用的是自定义(合成)事件, 而不是使用的原生DOM事件,也就是说react将所有事件在原生基础上进行了一个封装
- –为了更好的兼容性
- –为了更加高效–通过事件委托方式处理的(委托给组件最外层的元素)
- React使用的是自定义(合成)事件, 而不是使用的原生DOM事件,也就是说react将所有事件在原生基础上进行了一个封装
- 绑定的是函数而不是函数调用
- 实现原理不同,react在调用render函数时会先获取vdom,若是发现存在事件绑定,
- 若是绑定的值为一个函数那么就是在事件触发时 直接调用该函数
- 若是绑定的值为函数调用 ,那么会在调用render函数的时候同时会将该函数调用-> 相当于给事件绑定的是该函数的返回值了
- 实现原理不同,react在调用render函数时会先获取vdom,若是发现存在事件绑定,
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>
- 1.通过显示绑定-bind