简介
事件通常代表了用户和应用程序之间的某种类型的交互--任何时候用户点击对象、在输入框中输入、拖放某些元素,等等。因此,每个事件通常需要应用程序做出某种类型的反应。每当一个重要的事件发生时,作为程序员,我们可以定义一个用于响应所发生事件的函数。这些函数被称为事件处理程序,它们是任何编程语言中事件管理的核心。事件管理是一套用于处理事件的技术。
React也不例外!在本指南中,我们将深入挖掘React中事件管理的概念。我们将看一下几种不同类型的事件,以及用于处理这些事件的机制。
DOM和React事件处理之间的差异
如果你正在使用React,你可能已经熟悉了JavaScript中的DOM事件。
<!- JavaScript event ->
<button onclick="handleClick()">
Trigger Function
</button>
这就是onclick DOM事件。当这个例子的按钮被点击时,handleClick() 函数被调用--这就是事件管理的基本原则。这个基本思想在JavaScript和React之间是共享的,但有一些细微的差别区别于它们两个。
首先,在事件命名上有一个细微的差别--React使用骆驼字母的名字,而不是JavaScript使用的小写名字。在快速浏览了前面的例子后,你会发现事件的名称是onclick ,而React的替代名称是onClick 。此外,React使用JSX(JavaScript XML),它允许我们传递一个函数作为事件处理程序(在大括号内)而不是一个字符串。
<!- React event ->
<button onClick={handleClick}>
Trigger Function
</button>
注意我们没有在大括号内调用handleClick 函数--通过{handleClick()} 来调用它,每次元素被渲染时都会调用处理函数。我们所使用的语法确保处理函数只在事件被注册时被调用。
很多时候,你会发现自己处于这样的情况:你想在事件被注册后阻止默认行为。例如,onsubmit JavaScript事件在用户点击提交按钮后被注册。默认行为是适当地发送表单数据并重新加载网页,但我们可能需要防止重新加载网页。JavaScript在它的袖子里有一个防止默认行为的方便的技巧。
<form onsubmit="console.log('You clicked submit.'); return false">
<button type="submit">Submit</button>
</form>
我们以通常的方式定义了处理函数,但注意到我们在处理函数的定义后面添加了return false 。这就是JavaScript开发者在处理事件时防止默认行为的方法。如果你不在这个例子中的处理函数后面加上return false ,那么在控制台有机会记录消息之前,页面就会重新加载。
**注意:**事件处理函数可以在一个JavaScript文件中定义,并在检测到事件时在HTML中调用。另外,你也可以直接在HTML代码中定义并调用处理函数(正如你在上面的例子中看到的)。
React根本不支持这一招!为了防止React中的默认行为,你必须明确地调用preventDefault 。
function Form() {
function handleSubmit(e) {
e.preventDefault();
console.log("You clicked submit.");
}
return (
<form onSubmit={handleSubmit}>
<button type="submit">Submit</button>
</form>
);
}
也许不像JavaScript中的事件处理那么简单,但肯定是一种更强大的处理事件的方式。这个例子说明了事件处理在React的一个功能组件中的应用。我们只是在组件中声明了一个处理函数,并在return() 方法中调用它。
**注意:React负责处理跨浏览器的兼容性,所以你不需要担心这个问题。
在功能组件中处理事件
事件处理程序作为一个属性传递给功能组件中的元素或组件。当用户与该元素互动时,该属性会收到一个描述所发生情况的函数。
处理onClick事件
如果用户多次点击元素,onClick 事件被触发,函数被多次调用,就像任何其他事件一样。让我们看看实际情况如何,我们将创建一个按钮并调用一个函数。
const App = () => {
const handleClick = () => {
console.log("This function has been triggered!");
};
return (
<div className="App">
<h1>Hello World</h1>
<button onClick={handleClick}>Trigger Function</button>
</div>
);
};
这将在控制台中记录出"此函数已被触发!"。
向事件中传递参数
如果我们想向被触发的函数传递参数或值,我们必须使用一个箭头函数或一个实际的函数。在我们的例子中,假设我们想向函数传递一个值,然后在控制台中记录它。
const App = () => {
const handleClick = (name) => {
console.log("My Name is:", name);
};
return (
<div className="App">
<h1>Hello World</h1>
<button onClick={() => handleClick("John Doe")}>
Trigger Function
</button>
</div>
);
};
这将显示 "我的名字是。John Doe"在控制台中。我们也可以使用函数关键字来使用一个实际的函数,一切都将完美地工作。
<button onClick={function(){handleClick('John Doe')}}>Trigger Function</button>
处理onSubmit事件
当用户点击提交按钮或敲击键盘上的回车键时,我们也可以用React处理表单提交事件。这与onClick 事件的处理方式类似。
const App = () => {
const handleSubmit = () => {
console.log("The submit button was clicked!");
};
return (
<div className="App">
<h1>Hello World</h1>
<form onSubmit={handleSubmit}>
<label>Name</label>
<input type="text" />
<button type="submit">Submit</button>
</form>
</div>
);
};
"提交按钮被点击了!"将因此而被注销。然而,由于浏览器将立即重新加载,我们将使用preventDefault() 方法来防止浏览器执行默认动作。
const handleSubmit = (e) => {
e.preventDefault();
console.log("The submit button was clicked!");
};
在类组件中处理事件
类组件处理事件的方式与功能组件类似,但有一些小的区别。让我们创建一个按钮,在点击时调用handleClick 函数。
class App extends React.Component {
handleClick = () => {
console.log("This function has been triggered!");
};
render() {
return (
<div className="App">
<h1>Hello World</h1>
<button onClick={this.handleClick}>Trigger Function</button>
</div>
);
}
}
**注意:我们必须使用this 关键字,因为我们在App 类中,而handleClick 是该类中的一个成员函数。
向事件中传递参数
最好的做法是将处理函数声明为类组件中的一个方法。如果你想以后向渲染的组件传递参数、道具或状态,你必须在构造函数中把事件处理函数绑定到this 。
比方说,我们有一个状态值设置,我们想在特定的按钮被点击时进行改变,我们想使用传递的参数,我们会有这样的东西,但它会抛出一个错误。
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
title: "Welcome, We are glad you are here!"
};
}
handleClick = (name) => {
console.log("This function has been triggered!", name);
this.setState({
title: `Hello ${name}!`
});
};
render() {
return (
<div className="App">
<h1>{this.state.title}</h1>
<button onClick={this.handleClick("Joel")}>
Trigger Function
</button>
</div>
);
}
}
为了解决这个问题,我们要么使用箭头函数或者 Function.prototype.bind]来绑定this 关键字。
<button onClick={() => this.handleClick("John Doe")}>Trigger Function</button>
<button onClick={this.handleClick.bind(this, "John Doe")}>Trigger Function</button>
处理onSubmit事件
我们也可以用类组件来处理所有类型的事件,只要我们在声明方法时使用this 关键字而不是函数。
class App extends React.Component {
handleSubmit = (e) => {
e.preventDefault();
console.log("The submit button was clicked!");
};
render() {
return (
<div className="App">
<h1>Hello World</h1>
<form onSubmit={this.handleSubmit}>
<label>Name</label>
<input type="text" />
<button type="submit">Submit</button>
</form>
</div>
);
}
}
结语
我们在本指南中看到,React事件与JavaScript事件非常相似,只是在语法和传播行为上有一些区别。我们还学习了功能组件和类组件中使用的事件处理程序的区别,类组件需要将处理程序绑定到this 。在React中可以处理的事件还有很多,但无论在功能组件还是类组件中,它们的功能都与onClick 方法相同。