目录
扩展学习资料
React事件和DOM事件
和传统DOM事件处理异同
this关键字的处理
this关键字
在JSX中使用bind方法
在构造函数中使用bind方法
使用箭头函数【推荐】
向事件处理程序传递参数【不跨组件】
向父组件传递参数
@/src/App.js
@/src/components/listItem.jsx
React事件机制
DOM事件
React事件
React事件要素
小结
练习
扩展学习资料
预习资料名称 | 链接 | 备注 |
源码分析事件 | React源码分析6 — React合成事件系统 - 知乎 | 扩展阅读 |
合成事件 | http://react.html.cn/docs/events.html |
React事件和DOM事件
import React, { Component } from 'react';
import style from './listitem.module.css';
import classnames from 'classnames/bind';
const cls = classnames.bind(style);
let count = 0;
class ListItem extends Component {
// 类的构造函数
// eslint-disable-next-line no-useless-constructor
constructor(props) {
// JS规定,子类的构造函数必须先调用一下super函数
// =>类似于call的继承:在这里super相当于把Component的constructor给执行了,
// 并且让方法中的this是ListItem的实例,
// super当中传递的实参都是在给Component的constructor传递。
super(props);
// super 除了在 constructor 里直接调用外还可以使用 super.xxx(…)
// 来调用父类上的某个原型方法,这同样是一种限定语法。
}
handleDecrease(e) {
console.log('----', e);
}
handleAdd() {
console.log('++++');
}
render() {
return (
<div className='row mb-3'>
<div className='col-6 themed-grid-col'>
<span style={{ fontSize: 22, color: '#710000' }}>
{this.props.data.name}
</span>
</div>
<div className='col-1 themed-grid-col'>
<span className={cls('price-tag')}>¥{this.props.data.price}</span>
</div>
{/* <div className={"col-2 themed-grid-col" + ( count ? '' : '-s') } >
{this.manageCount()}</div> */}
<div className={`col-2 themed-grid-col${count ? '' : '-s'}`}>
<button
onClick={this.handleDecrease}
type='button'
className='btn btn-primary'>
-
</button>
<span className={cls('digital')}>{this.manageCount()}</span>
<button
onClick={this.handleAdd}
type='button'
className='btn btn-primary'>
+
</button>
</div>
</div>
);
}
manageCount() {
return count ? count + '个' : count;
}
}
export default ListItem;
和传统DOM事件处理异同
this关键字的处理
this关键字
-
在JSX中使用bind方法
<button
// 这样写在handleDecrease函数中就可以使用this了
onClick={this.handleDecrease.bind(this)}
type='button'
className='btn btn-primary'>
-
</button>
-
在构造函数中使用bind方法
constructor(props) {
super(props);
// 这样写在handleAdd函数中就可以使用this了
this.handleAdd = this.handleAdd.bind(this);
}
-
使用箭头函数【推荐】
// 这样写在handleAdd函数中就可以使用this了
handleAdd = () => {
count++;
console.log('++++', this);
};
向事件处理程序传递参数【不跨组件】
方法一
onClick={this.handleDecrease.bind(this, 9)}
const count = 0;
doSomethingWithCount() {
if (count < 0) count = 0;
}
handleDecrease(id, event) {
console.log('----id:', id, this, event);
count--;
this.doSomethingWithCount();
}
方法二【推荐】
<button
onClick={(event) => {
this.handleDecrease(9, event);
}}
type='button'
className='btn btn-primary'>
-
</button>
向父组件传递参数
@/src/App.js
在父组件定义好事件处理函数,并通过props向子组件传递
//...
class App extends Component {
// 1.1定义
handleDelete = (id) => {
console.log("删除id: ", id);
};
render() {
return (
<div className="container">
{listData.length === 0 && (
<div className="text-center">购物车是空的</div>
)}
{listData.map((item) => {
return (
// 1.2传递
<ListItem key={item.id} data={item} onDelete={this.handleDelete} />
);
})}
</div>
);
}
}
//...
@/src/components/listItem.jsx
在子组件react元素上,绑定props传入的函数,并带入参数
// ...
onClick={()=> {this.props.onDelete(this.props.data.id)}}
onClick={this.props.onDelete.bind(this,this.props.data.id)}
// ...
React事件机制
DOM事件
【Dom事件的基本模型】事件捕获=>目标对象本身的事件处理=>冒泡
行为委托:就是把子元素的事件处理委托给父级元素进行处理
React事件
React事件机制抽象图
react会把所有的事件绑定到document上面,而不是某一个元素上面,统一的使用事件监听,并在冒泡阶段处理事件,所有当挂载卸载组件的时候,只需要在统一的事件监听位置增加或删除对象,因此会极大的提高效率。
当事件触发的时候,我们的组件会生成一个合成事件,
然后传递到document当中,
document会通过Dispatch Event回调函数依次执行dispatcher中同类型监听函数,
事件注册是在组件生成的时候我们将listen dom中的所有的事件对应的原生事件都注册到document的监听器当中(ListenerBank中)并以key作为索引
好处就是能将可能要触发的事件分门别类
React事件要素
- React事件是合成事件,不是DOM原生事件
- 在document监听所有的支持事件
- 使用统一的分发函数dispatchEvent指定事件的执行
小结
- 原生事件差异
- 事件处理中this的注意事项
- 事件处理如何传递参数
- 父子组件间事件参数的传递
- React事件机制
练习
【题目1】 使用bind方法和箭头函数传递参数。
【题目2】 描述事件在react中的处理方式。