ReactJS - 在Expense Manager APP中引入事件



在前面的章节中,我们了解到事件只是用户为与任何应用程序交互而执行的一些操作。它们可以是最小的操作,例如将鼠标指针悬停在触发下拉菜单的元素上、调整应用程序窗口的大小或拖放元素以上传它们等。

对于这些事件中的每一个,JavaScript 都会提供响应。因此,每次用户执行事件时,通常都需要应用程序做出某种类型的反应;这些反应被定义为一些函数或代码块,称为事件处理程序

为了更好地理解事件处理,我们尝试将事件引入到一个示例应用程序(Expense Manager APP)中。在本章中,我们将尝试在费用管理器应用程序中处理鼠标事件。鼠标事件只是用户使用鼠标执行的一些操作。其中包括悬停、单击、拖动或简单地使用鼠标在应用程序上执行的任何操作。

在Expense Manager APP中处理事件

让我们在费用应用程序中做一些事件管理。当用户将光标移到表中的费用分录项上时,我们可以尝试突出显示表中的费用分录项。

第 1 步 - 在您最喜欢的编辑器中打开费用管理器应用程序。

打开ExpenseEntryItemList.js文件并添加一个方法 handleMouseEnter,以处理当用户将鼠标指针移动到费用项目(td - 表单元格)时触发的事件 (onMouseEnter)。


handleMouseEnter(e) {	
	 	e.target.parentNode.classList.add("highlight");	
}

这里

  • 事件处理程序尝试使用 parentNode 方法查找事件目标 (td) 节点的父节点 (tr)。parentNode 方法是标准的 DOM 方法,用于查找直接父节点(即当前节点)。
  • 找到父节点后,事件处理程序将访问附加到父节点的 css 类的列表,并使用 add 方法添加“highlight”类。classList 是标准的 DOM 属性,用于获取附加到节点的类列表,可用于在 DOM 节点中添加/删除类。

第 2 步 - 接下来,添加一个方法 handleMouseLeave() 以处理用户移出费用项目时触发的事件。


handleMouseLeave(e) {	
	 	e.target.parentNode.classList.remove("highlight");	
}

在这里,事件处理程序从 DOM 中删除高亮类。

添加另一个方法 handleMouseOver() 以检查鼠标当前的位置。在 DOM 中查找鼠标指针的位置是可选的。


handleMouseOver(e) {	
	 	console.log("The mouse is at (" + e.clientX + ", " + e.clientY + ")");	
}

第 3 步 - 在组件的构造函数中绑定所有事件处理程序。


this.handleMouseEnter = this.handleMouseEnter.bind();	
this.handleMouseLeave = this.handleMouseLeave.bind();	
this.handleMouseOver = this.handleMouseOver.bind();

第 4 步 - 将事件处理程序附加到 render 方法中的相应标签。


render() {
	 	const lists = this.props.items.map((item) =>
	 	 	 <tr key={item.id} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>
	 	 	 	 	<td>{item.name}</td>
	 	 	 	 	<td>{item.amount}</td>
	 	 	 	 	<td>{new Date(item.spendDate).toDateString()}</td>
	 	 	 	 	<td>{item.category}</td>
	 	 	 </tr>
	 	);
	 	return (
	 	 	 <table onMouseOver={this.handleMouseOver}>
	 	 	 	 	<thead>
	 	 	 	 	 	 <tr>
	 	 	 	 	 	 	 	<th>Item</th>
	 	 	 	 	 	 	 	<th>Amount</th>
	 	 	 	 	 	 	 	<th>Date</th>
	 	 	 	 	 	 	 	<th>Category</th>
	 	 	 	 	 	 </tr>
	 	 	 	 	</thead>
	 	 	 	 	<tbody>
	 	 	 	 	 	 {lists}
	 	 	 	 	</tbody>
	 	 	 </table>
	 	);
}

ExpenseEntryItemList的最终完整代码如下:


import React from 'react';
import './ExpenseEntryItemList.css';

class ExpenseEntryItemList extends React.Component {
	 	constructor(props) {
	 	 	 super(props);

	 	 	 this.handleMouseEnter = this.handleMouseEnter.bind();
	 	 	 this.handleMouseLeave = this.handleMouseLeave.bind();
	 	 	 this.handleMouseOver = this.handleMouseOver.bind();
	 	}
	 	handleMouseEnter(e) {
	 	 	 e.target.parentNode.classList.add("highlight");
	 	}
	 	handleMouseLeave(e) {
	 	 	 e.target.parentNode.classList.remove("highlight");
	 	}
	 	handleMouseOver(e) {
	 	 	 console.log("The mouse is at (" + e.clientX + ", " + e.clientY + ")");
	 	}
	 	render() {
	 	 	 const lists = this.props.items.map((item) =>
	 	 	 	 	<tr key={item.id} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>
	 	 	 	 	 	 <td>{item.name}</td>
	 	 	 	 	 	 <td>{item.amount}</td>
	 	 	 	 	 	 <td>{new Date(item.spendDate).toDateString()}</td>
	 	 	 	 	 	 <td>{item.category}</td>
	 	 	 	 	</tr>
	 	 	 );
	 	 	 return (
	 	 	 	 	<table onMouseOver={this.handleMouseOver}>
	 	 	 	 	 	 <thead>
	 	 	 	 	 	 	 	<tr>
	 	 	 	 	 	 	 	 	 <th>Item</th>
	 	 	 	 	 	 	 	 	 <th>Amount</th>
	 	 	 	 	 	 	 	 	 <th>Date</th>
	 	 	 	 	 	 	 	 	 <th>Category</th>
	 	 	 	 	 	 	 	</tr>
	 	 	 	 	 	 </thead>
	 	 	 	 	 	 <tbody>
	 	 	 	 	 	 	 	{lists}
	 	 	 	 	 	 </tbody>
	 	 	 	 	</table>
	 	 	 );
	 	}
}
export default ExpenseEntryItemList;

ExpenseEntryItemList.css:

接下来,打开 css 文件,ExpenseEntryItemList.css并添加一个 css 类,突出显示。


tr.highlight td {	
	 	background-color: #a6a8bd;	
}

index.js

打开 index.js并使用 ExpenseEntryItemList 组件。


import React from 'react';
import ReactDOM from 'react-dom';
import ExpenseEntryItemList from './components/ExpenseEntryItemList'

const items = [
	 	{ id: 1, name: "Pizza", amount: 80, spendDate: "2020-10-10", category: "Food" },
	 	{ id: 2, name: "Grape Juice", amount: 30, spendDate: "2020-10-12", category: "Food" },
	 	{ id: 3, name: "Cinema", amount: 210, spendDate: "2020-10-16", category: "Entertainment" },
	 	{ id: 4, name: "Java Programming book", amount: 242, spendDate: "2020-10-15", category: "Academic" },
	 	{ id: 5, name: "Mango Juice", amount: 35, spendDate: "2020-10-16", category: "Food" },
	 	{ id: 6, name: "Dress", amount: 2000, spendDate: "2020-10-25", category: "Cloth" },
	 	{ id: 7, name: "Tour", amount: 2555, spendDate: "2020-10-29", category: "Entertainment" },
	 	{ id: 8, name: "Meals", amount: 300, spendDate: "2020-10-30", category: "Food" },
	 	{ id: 9, name: "Mobile", amount: 3500, spendDate: "2020-11-02", category: "Gadgets" },
	 	{ id: 10, name: "Exam Fees", amount: 1245, spendDate: "2020-11-04", category: "Academic" }
]
ReactDOM.render(
	 	<React.StrictMode>
	 	 	 <ExpenseEntryItemList items={items} />
	 	</React.StrictMode>,
	 	document.getElementById('root')
);

使用 npm 命令为应用程序提供服务。

npm start

打开浏览器,在地址栏中输入 http://localhost:3000,然后按回车键。

应用程序将响应鼠标事件并突出显示当前选定的行。

项目 日期 类别
Pizza 80 Sat Oct 10 2020 Food
Grape Juice 30 Man Oct 12 2020 Food
Cinema 210 Fri Oct 16 2020 Entertainment
Java Programming book 242 Thu Oct 15 2020 Academic
Mango Juice 35 Fri Oct 16 2020 Food
Dress 2000 Sun Oct 25 2020 Cloth
Tour 2555 Thu Oct 29 2020 Entertainment
Meals 300 Fri Oct 30 2020 Food
Mobile 3500 Mon Nov 02 2020 Gadgets
Exam Fees 1245 Wed Nov 04 2020 Academic