開發環境: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() 阻止少數事件的默認瀏覽器行為。