开发环境:React+ts+antd
使用 React 可以在 JSX 中添加 事件处理函数。其中事件处理函数为自定义函数,它将在响应交互(如点击、悬停、表单输入框获得焦点等)时触发。
学习内容
1.编写事件处理函数的不同方法
2.如何从父组件传递事件处理逻辑
3.事件如何传播以及如何停止它们
添加事件处理函数
如需添加一个事件处理函数,你需要先定义一个函数,然后 将其作为 prop 传入 合适的 JSX 标签。
import React from "react";
import { Button } from 'antd';const App:React.FC=()=>{const handleClick = () => {alert('你点击了按钮!')}return (<div><Button type="primary" onClick={handleClick}>点我看看</Button></div>)
}export default App
你可以定义 handleClick 函数然后 将其作为 prop 传入 。其中 handleClick 是一个 事件处理函数 。事件处理函数有如下特点:
- 通常在你的组件 内部 定义。
- 名称以 handle 开头,后跟事件名称。
或者,你也可以在 JSX 中定义一个内联的事件处理函数:
<Button type="primary" onClick={() => {alert('你点击了按钮');
}}>点我看看</Button>
在事件处理函数中读取 props
由于事件处理函数声明于组件内部,因此它们可以直接访问组件的 props。示例中的按钮,当点击时会弹出带有 message prop 的 alert:
import React from "react";
import { Button } from 'antd';interface MessagePro{message:stringchildren:React.ReactNode
}const AlertButton:React.FC<MessagePro> = ({message,children}) => {return(<Button type="primary" onClick={()=>{alert(message)}}>{children}</Button>)
}const App:React.FC=()=>{return (<div><div><AlertButton message="正在播放!">播放电影</AlertButton><AlertButton message="正在上传!">上传图片</AlertButton></div></div>)
}export default App
将事件处理函数作为 props 传递
通常,我们会在父组件中定义子组件的事件处理函数。比如:置于不同位置的 Button 组件,可能最终执行的功能也不同 —— 也许是播放电影,也许是上传图片。
为此,将组件从父组件接收的 prop 作为事件处理函数传递,如下所示:
import React from 'react';
import {Button as AntdButton} from 'antd';// 自定义 Button 组件的 props 类型
interface CustomButtonProps {onClick: () => void,children: React.ReactNode,variant: any,color:any,
}// 自定义 Button 组件
const CustomButton: React.FC<CustomButtonProps> = ({onClick, children, variant,color}) => {return (<AntdButton onClick={onClick} variant={variant} color={color}>{children}</AntdButton>);
};// PlayButton 组件的 props 类型
interface PlayButtonProps {movieName: string;
}// PlayButton 组件
const PlayButton: React.FC<PlayButtonProps> = ({movieName}) => {const handlePlayClick = () => {alert(`正在播放 ${movieName}!`);};return (<CustomButton onClick={handlePlayClick} variant="solid" color="blue">播放 "{movieName}"</CustomButton>);
};// UploadButton 组件
const UploadButton: React.FC = () => {return (<CustomButton onClick={() => alert('正在上传!')} variant="solid" color="red">上传图片</CustomButton>);
};// Toolbar 组件
const Toolbar: React.FC = () => {return (<div><PlayButton movieName="斯巴达克斯"/><UploadButton/></div>);
};export default Toolbar;
事件传播
事件处理函数还将捕获任何来自子组件的事件。通常,我们会说事件会沿着树向上“冒泡”或“传播”:它从事件发生的地方开始,然后沿着树向上传播。
下面这个
import React from 'react';
import { Button as AntdButton } from 'antd';// 定义自定义按钮组件的 props 类型
interface CustomButtonProps {onClick: () => void;children: React.ReactNode;
}// 自定义按钮组件
const CustomButton: React.FC<CustomButtonProps> = ({ onClick, children }) => {const handleClick = () => {onClick();};return (<AntdButton onClick={handleClick} type="primary">{children}</AntdButton>);
};// Toolbar 组件
const Toolbar: React.FC = () => {return (<div className="Toolbar" style={{background:'gray',padding:'20px',}} onClick={() => {alert('你点击了 toolbar !');}}><CustomButton onClick={() => alert('正在播放!')}>播放电影</CustomButton><CustomButton onClick={() => alert('正在上传!')}>上传图片</CustomButton></div>);
};export default Toolbar;
如果你点击任一按钮,它自身的 onClick 将首先执行,然后父级
阻止传播
事件处理函数接收一个 事件对象 作为唯一的参数。按照惯例,它通常被称为 e ,代表 “event”(事件)。你可以使用此对象来读取有关事件的信息。
这个事件对象还允许你阻止传播。如果你想阻止一个事件到达父组件,你需要像下面 Button 组件那样调用 e.stopPropagation() :
import React from 'react';
import { Button as AntdButton } from 'antd';// 定义自定义按钮组件的 props 类型
interface CustomButtonProps {onClick: () => void;children: React.ReactNode;
}// 自定义按钮组件
const CustomButton: React.FC<CustomButtonProps> = ({ onClick, children }) => {const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {e.stopPropagation();onClick();};return (<AntdButton onClick={handleClick} type="primary">{children}</AntdButton>);
};// Toolbar 组件
const Toolbar: React.FC = () => {return (<div className="Toolbar" style={{background:'gray',padding:'20px',}} onClick={() => {alert('你点击了 toolbar !');}}><CustomButton onClick={() => alert('正在播放!')}>播放电影</CustomButton><CustomButton onClick={() => alert('正在上传!')}>上传图片</CustomButton></div>);
};export default Toolbar;
由于调用了 e.stopPropagation(),点击按钮现在将只显示一个 alert(来自 ),而并非两个(分别来自 和父级 toolbar
阻止默认行为
某些浏览器事件具有与事件相关联的默认行为。例如,点击 表单内部的按钮会触发表单提交事件,默认情况下将重新加载整个页面:
import React from 'react';// Toolbar 组件
const Toolbar: React.FC = () => {return (<div className="Toolbar" style={{background: 'gray', padding: '20px',}}><form onSubmit={() => alert('提交表单!')}><input/><button>发送</button></form></div>);
};export default Toolbar;
你可以调用事件对象中的 e.preventDefault() 来阻止这种情况发生:
import React from 'react';// Toolbar 组件
const Toolbar: React.FC = () => {return (<div className="Toolbar" style={{background: 'gray', padding: '20px',}}><form onSubmit={(e) => {e.preventDefault();alert('提交表单!')}}><input/><button>发送</button></form></div>);
};export default Toolbar;
不要混淆 e.stopPropagation() 和 e.preventDefault()。它们都很有用,但二者并不相关:
- e.stopPropagation() 阻止触发绑定在外层标签上的事件处理函数。
- e.preventDefault() 阻止少数事件的默认浏览器行为。