添加交互#
约 4757 个字 746 行代码 2 张图片 预计阅读时间 104 分钟
响应事件#
创建事件处理函数#
JSX
export default function Button() {
function handleClick() {
alert('你点击了我!');
}
return (
<button onClick={handleClick}>
点我
</button>
);
}
handleClick是一个事件处理函数
,事件处理函数
有如下特点:
- 通常在你的组件
内部
定义。 - 名称以
handle
开头,后跟事件名称。
或者,你也可以在 JSX 中定义一个内联的事件处理函数:
或者,直接使用更为简洁箭头函数:
传递给事件处理函数的函数应直接传递,而非调用。
传递一个函数(正确) | 调用一个函数(错误❌) |
---|---|
<button onClick={handleClick}> | <button onClick={handleClick()}> |
在第一个示例中,handleClick 函数作为 onClick 事件处理函数传递。这会让 React 记住它,并且只在用户点击按钮时调用你的函数。 | 第二个示例中,handleClick() 中最后的 () 会在 渲染 过程中 立即 触发函数,即使没有任何点击。这是因为位于 JSX {} 之间的 JavaScript 会立即执行。 |
事件处理函数读取props#
由于事件处理函数声明于组件内部,因此它们可以直接访问组件的 props。
JSX
function AlertButton({ message, children }) {
return (
<button onClick={() => alert(message)}>
{children}
</button>
);
}
export default function Toolbar() {
return (
<div>
<AlertButton message="正在播放!">
播放电影
</AlertButton>
<AlertButton message="正在上传!">
上传图片
</AlertButton>
</div>
);
}
父组件定义事件处理函数#
在父组件中定义子组件的事件处理函数。不同的子组件,最总执行的事件处理函数可能是不同的。为此,将组件从父组件接收的 prop 作为事件处理函数传递。
JSX
function Button({onClick, children}) {
return <button onClick={onClick}>{children}</button>;
}
export default function Toolbar() {
function handlePlayClick() {
alert(`正在播放!`);
}
return (
<div>
<Button onClick={handlePlayClick}>播放电影</Button>
<Button onClick={() => alert("正在上传!")}>上传图片</Button>
</div>
);
}
命名事件处理函数 prop
按照惯例,事件处理函数 props 应该以 on 开头,后跟一个大写字母。
事件传播问题#
事件处理函数还将捕获任何来自子组件的事件。通常,我们会说事件会沿着树向上冒泡
或传播
:它从事件发生的地方开始,然后沿着树向上传播。
在 React 中所有事件都会传播,除了 onScroll,它仅适用于你附加到的 JSX 标签。
JSX
/*
* 如果你点击任一按钮,它自身的 onClick 将首先执行,
* 然后父级 <div> 的 onClick 会接着执行。
* 因此会出现两条消息。
* 如果你点击 toolbar 本身,
* 将只有父级 <div> 的 onClick 会执行。
* */
export default function Toolbar() {
return (
<div className="Toolbar" onClick={() => {
alert('你点击了 toolbar !');
}}>
<button onClick={() => alert('正在播放!')}>
播放电影
</button>
<button onClick={() => alert('正在上传!')}>
上传图片
</button>
</div>
);
}
调用 e.stopPropagation()
,阻止事件进一步向上冒泡。
JSX
export default function Toolbar() {
return (
<div className="Toolbar" onClick={() => {
alert('你点击了 toolbar !');
}}>
<button onClick={e => {
// 阻止事件向上传播
e.stopPropagation();
alert('正在播放!');
}}>
播放电影
</button>
<button onClick={() => alert('正在上传!')}>
上传图片
</button>
</div>
);
}
也可以让子组件处理事件
,同时也让父组件指定一些额外的行为
。与事件传播不同,它并非自动。但使用这种模式的好处是你可以清楚地 追踪因某个事件的触发而执行的整条代码链
。如果你依赖于事件传播,而且很难追踪哪些处理程序在执行,及其执行的原因,可以尝试这种方法。
JSX
function Button({ onClick, children }) {
return (
<button onClick={e => {
e.stopPropagation();
onClick();
}}>
{children}
</button>
);
}
阻止默认行为#
某些浏览器事件具有与事件相关联的默认行为。例如,点击