响应事件
添加事件处理函数
命名方式:
- 通常在你的组件 内部 定义。
- 名称以
handle
开头,后跟事件名称。
内联事件处理函数:
<button onClick={function handleClick() {
alert('你点击了我!');
}}>
//箭头函数
<button onClick={() => {
alert('你点击了我!');
}}>
注意: 传递给事件处理函数的函数应直接传递,而非调用
传递一个函数: handleClick
函数作为 onClick
事件处理函数传递。这会让 React 记住它,并且只在用户点击按钮时调用你的函数
<button onClick={handleClick}>
调用一个函数(错误):handleClick()
中最后的 ()
会在 渲染过程中立即 触发函数,即使没有任何点击。这是因为在JSX {
和 }
之间的 JavaScript 会立即执行
<button onClick={handleClick()}>
通常,我们会在父组件中定义子组件的事件处理函数。
事件传播
事件处理函数还将捕获任何来自子组件的事件。通常,我们会说事件会沿着树向上“冒泡”或“传播”:它从事件发生的地方开始,然后沿着树向上传播。
React中所有事件都会传播,处理onScroll
,它仅适用于附加到的JSX标签。
阻止传播
事件处理函数接收一个 事件对象 作为唯一的参数。按照惯例,它通常被称为 e
,代表 “event”(事件)。你可以使用此对象来读取有关事件的信息。
这个事件对象还允许你阻止传播。如果你想阻止一个事件到达父组件,你需要像下面 Button
组件那样调用 e.stopPropagation()
:
<button onClick={e => {
e.stopPropagation();
onClick();
}}>
{children}
</button>
捕获阶段事件
有时候需要,捕获子元素上所有事件,即便它们阻止了传播,那么可以通过事件名称末尾添加Capture
来实现:
<div onClickCapture={() => { /* 这会首先执行 */ }}>
<button onClick={e => e.stopPropagation()} />
<button onClick={e => e.stopPropagation()} />
</div>
每个事件分三个阶段传播:
- 它向下传播,调用所有的
onClickCapture
处理函数。 - 它执行被点击元素的
onClick
处理函数。 - 它向上传播,调用所有的
onClick
处理函数。
阻止默认行为
某些浏览器时间就有与事件相关联的默认行为,如点击 <form>
表单内部的按钮会触发表单提交事件,默认情况下将重新加载整个页面:
export default function Signup() {
return (
<form onSubmit={() => alert('提交表单!')}>
<input />
<button>发送</button>
</form>
);
}
可以通过调用事件对象的e.preventDefault()
来阻止默认事件。
不要混淆 e.stopPropagation()
和 e.preventDefault()
。它们都很有用,但二者并不相关:
e.stopPropagation()
阻止触发绑定在外层标签上的事件处理函数。e.preventDefault()
阻止少数事件的默认浏览器行为。
事件处理函数可以包含副作用
事件处理函数是执行副作用的最佳位置。 与渲染函数不同,事件处理函数不需要是 纯函数,因此它是用来 更改 某些值的绝佳位置。例如,更改输入框的值以响应键入,或者更改列表以响应按钮的触发。但是,为了更改某些信息,你首先需要某种方式存储它。在 React 中,这是通过 state(组件的记忆) 来完成的。