React学习笔记-事件(三)
定义事件
React 元素的事件处理和 DOM 元素的很相似 但是有一点语法上的不同
React 事件的命名采用小驼峰式(camelCase)而不是纯小写 如点击事件onClick
import React from 'react'
export default class learnEvent extends React.Component {
// // 直接在类里面定义一个方法
hello () {
console.log('hello word')
}
render () {
return (
<div>
{/* 直接在类里面定义一个方法 事件使用小驼峰*/}
<button onClick={this.hello}>直接定义</button>
</div>
)
}
}
this指向问题
import React from 'react'
export default class learnEvent extends React.Component {
// word的执行上下文为Window 由于jsx经babel编译后会开启严格模式。
// 所以this指向变为undefined
word () {
console.log(this)
}
render () {
return (
<div>
<button onClick={this.word}>this指向</button>
</div>
)
}
}
解决this指向问题-bind改变指向
import React from 'react'
export default class learnEvent extends React.Component {
// 用bind改变this指向
wordBind () {
console.log(this)
}
render () {
return (
<div>
{/* 使用bind将this指向改到render上 render的this又指向实例对象 call和apply会自动执行不能使用
尽量使用es6语法 bind不推荐使用 */}
<button onClick={this.wordBind.bind(this)}>binb改变指向</button>
</div>
)
}
}
解决this指向问题-ES6箭头函数
import React from 'react'
export default class learnEvent extends React.Component {
// es6箭头函数
wordES6 = () => {
console.log(this);
}
render () {
return (
<div>
{/* 箭头函数没有this 里面的this是箭头函数所处环境上下文this指向 在这里箭头函数外this指向实例对象
这种方法无法传参 不推荐使用
有性能影响 可以忽略不记 */}
<button onClick={this.wordES6}>es6箭头函数</button>
</div>
)
}
}
获取事件对象event
import React from 'react'
export default class learnEvent extends React.Component {
// 获取事件event对象
helloEvent(event) {
console.log(event)
}
render () {
return (
<div>
{/* 获取事件event对象 */}
<button onClick={(event) => {this.helloEvent(event)}}>获取事件event对象</button>
</div>
)
}
}
合成事件
概念
React 合成事件(SyntheticEvent)是 React 模拟原生 DOM 事件所有能力的一个事件对象 即浏览器原生事件的跨浏览器包装器 它根据 W3C 规范 来定义合成事件 兼容所有浏览器 拥有与浏览器原生事件相同的接口
// 这个onClick就是合成事件
<button onClick={xxx}>+1</button>
合成事件优势
进行浏览器兼容 实现更好的跨平台
- React 采用的是顶层事件代理机制 能够保证冒泡一致性 可以跨浏览器执行 React 提供的合成事件用来抹平不同浏览器事件对象之间的差异 将不同平台事件模拟合成事件
避免垃圾回收
- 事件对象可能会被频繁创建和回收 因此 React 引入事件池 在事件池中获取或释放事件对象 即 React 事件对象不会被释放掉 而是存放进一个数组中 当事件触发 就从这个数组中弹出 避免频繁地去创建和销毁(垃圾回收)
方便事件统一管理和事务机制
合成事件和原生事件区别
a. 事件命名方式
// 原生事件命名为纯小写(onclick, onblur) 而 React 事件命名采用小驼峰式(camelCase) 如 onClick 等
// 原生事件绑定方式
<button onclick="handleClick()">+1</button>
// React 合成事件绑定方式
const button = <button onClick={handleClick}>+1</button>
b. 事件处理函数写法
// 原生事件中事件处理函数为字符串 在 React JSX 语法中 传入一个函数作为事件处理函数
// 原生事件 事件处理函数写法
<button onclick="handleClick()">+1</button>
// React 合成事件 事件处理函数写法
const button = <button onClick={handleClick}>+1</button>
c. 阻止默认行为方式
// 在原生事件中,可以通过返回 false 方式来阻止默认行为 但是在 React 中 需要显式使用 preventDefault() 方法来阻止
// 原生事件阻止默认行为方式
<a href="#"
onclick="console.log('阻止原生事件'); return false"
>
阻止原生事件
</a>
// React 事件阻止默认行为方式
const handleClick = e => {
e.preventDefault();
console.log('阻止原生事件~');
}
const clickElement = <a href="#" onClick={handleClick}>
阻止原生事件
</a>
React事件和原生事件执行顺序
- React 所有事件都挂载在 document 对象上
- 当真实 DOM 元素触发事件 会冒泡到 document 对象后 再处理 React 事件
- 所以会先执行原生事件 然后处理 React 事件
- 最后真正执行 document 上挂载的事件