React TypeScript 从点击事件中获取数据属性
React TypeScript get Data Attribute From Click Event
所以我有一个带有按钮的 React 组件,该按钮有一个使用 data-* 属性的点击处理程序。如果这是直接的 React,那么我知道如何从 data-* 属性中获取值。但是我正在学习如何使用 TypeScript,所以我不知道如何访问这个属性。那么使用 TypeScript 访问 data-* 属性的最佳方法是什么?
这是我的按钮 JSX 代码:
<button type="button" className="NavLink" data-appMode={ AppMode.MAIN } onClick={ this.handleAppModeClick.bind(this) }>Main</button>
这是我的点击事件处理程序:
handleAppModeClick(e: React.MouseEvent<HTMLElement>) {
// What code should go here to access the data-appMode attribute?
}
在您的事件函数中,您有 e 变量,e 表示通过单击按钮触发的事件,e 有一个目标 属性 因此,为了访问元素的属性,您应该这样做:
handleAppModeClick(e: React.MouseEvent<HTMLElement>) {
const target = e.target as HTMLElement;
let attr = target.getAttribute("data-attribute-name-here");
//do something
}
您很可能必须使用 as
语法,具体取决于您想在 e.target.
上访问哪个 属性
handleAppModeClick(e: React.MouseEvent) {
const appMode = (e.target as HTMLButtonElement).getAttribute('data-appMode');
}
使用e.currentTarget然后使用HTML标准方法getAttribute
。无需强制。
const appMode = e.currentTarget.getAttribute('data-appmode');
(注意属性名称中的小写以避免反应警告)
currentTarget
已正确输入。
如果您阅读 the definitions of React's event types,您会看到 MouseEvent
扩展了 SyntheticEvent
,后者扩展了 BaseSyntheticEvent
,其中包括 属性 target
和 currentTarget
,等等。您提供的 HTMLElement
类型将应用于 currentTarget
,因此您可以访问所有正确的内容。如果你使用 target
你会得到一个关于 getAttribute
not being valid for type EventTarget
.
的编译错误
有什么区别?
currentTarget
是您放置处理程序的元素,onClick
。 target
是事件最初的来源(more here). This is not necessarily the same because events bubble up. See the PR referenced in the type definitions file 以完整讨论为什么它们的类型不同。
使用打字稿我最近了解到以下方法:
type TabsProps = {
activeTab: string,
items: string[],
setActiveTab: (i: string) => void,
}
const Tabs = ({ items, activeTab, setActiveTab }: TabsProps) => {
const onClick: React.MouseEventHandler<HTMLElement> = (e) => {
setActiveTab(e.currentTarget.dataset.id)
//console.log(e) // <a data-id="0" class="active nav-link">Info</a>
}
return (
<Nav tabs >
{
items.map((x, i) => (
<NavItem key={i}>
<NavLink className={activeTab === i.toString() ? 'active' : ''} onClick={onClick} data-id={i}>{x}</NavLink>
</NavItem>
))
}
</Nav >
);
}
所以我有一个带有按钮的 React 组件,该按钮有一个使用 data-* 属性的点击处理程序。如果这是直接的 React,那么我知道如何从 data-* 属性中获取值。但是我正在学习如何使用 TypeScript,所以我不知道如何访问这个属性。那么使用 TypeScript 访问 data-* 属性的最佳方法是什么?
这是我的按钮 JSX 代码:
<button type="button" className="NavLink" data-appMode={ AppMode.MAIN } onClick={ this.handleAppModeClick.bind(this) }>Main</button>
这是我的点击事件处理程序:
handleAppModeClick(e: React.MouseEvent<HTMLElement>) {
// What code should go here to access the data-appMode attribute?
}
在您的事件函数中,您有 e 变量,e 表示通过单击按钮触发的事件,e 有一个目标 属性 因此,为了访问元素的属性,您应该这样做:
handleAppModeClick(e: React.MouseEvent<HTMLElement>) {
const target = e.target as HTMLElement;
let attr = target.getAttribute("data-attribute-name-here");
//do something
}
您很可能必须使用 as
语法,具体取决于您想在 e.target.
handleAppModeClick(e: React.MouseEvent) {
const appMode = (e.target as HTMLButtonElement).getAttribute('data-appMode');
}
使用e.currentTarget然后使用HTML标准方法getAttribute
。无需强制。
const appMode = e.currentTarget.getAttribute('data-appmode');
(注意属性名称中的小写以避免反应警告)
currentTarget
已正确输入。
如果您阅读 the definitions of React's event types,您会看到 MouseEvent
扩展了 SyntheticEvent
,后者扩展了 BaseSyntheticEvent
,其中包括 属性 target
和 currentTarget
,等等。您提供的 HTMLElement
类型将应用于 currentTarget
,因此您可以访问所有正确的内容。如果你使用 target
你会得到一个关于 getAttribute
not being valid for type EventTarget
.
有什么区别?
currentTarget
是您放置处理程序的元素,onClick
。 target
是事件最初的来源(more here). This is not necessarily the same because events bubble up. See the PR referenced in the type definitions file 以完整讨论为什么它们的类型不同。
使用打字稿我最近了解到以下方法:
type TabsProps = {
activeTab: string,
items: string[],
setActiveTab: (i: string) => void,
}
const Tabs = ({ items, activeTab, setActiveTab }: TabsProps) => {
const onClick: React.MouseEventHandler<HTMLElement> = (e) => {
setActiveTab(e.currentTarget.dataset.id)
//console.log(e) // <a data-id="0" class="active nav-link">Info</a>
}
return (
<Nav tabs >
{
items.map((x, i) => (
<NavItem key={i}>
<NavLink className={activeTab === i.toString() ? 'active' : ''} onClick={onClick} data-id={i}>{x}</NavLink>
</NavItem>
))
}
</Nav >
);
}