![]() |
爱跑步的电池 · Meta 教你5步学会用 ...· 4 月前 · |
![]() |
聪明伶俐的围巾 · [886]mysql查询以某个字符开头_my ...· 1 年前 · |
![]() |
兴奋的口罩 · 政体学说 - 《中国大百科全书》第三版网络版· 1 年前 · |
事件和反应事件类型的TypeScript DOM类型可能与另一个事件类型不太匹配吗?
看看这段代码:
useEffect(() => {
const onScroll = (event: React.ChangeEvent<Body>) => {
console.log("event", event.target);
window.addEventListener("scroll", onScroll);
return () => window.removeEventListener("scroll", onScroll);
}, []);
它抛出
No overload matches this call.
Overload 1 of 2, '(type: "scroll", listener: (this: Window, ev: Event) => any, options?: boolean | AddEventListenerOptions | undefined): void', gave the following error.
Argument of type '(event: ChangeEvent<Body>) => void' is not assignable to parameter of type '(this: Window, ev: Event) => any'.
Types of parameters 'event' and 'ev' are incompatible.
Type 'Event' is not assignable to type 'ChangeEvent<Body>'.
比我试过的更好。这将正确编译。
useEffect(() => {
const onScroll = (event: Event) => { // <--- changed event type here
console.log("event", event.target);
window.addEventListener("scroll", onScroll);
return () => window.removeEventListener("scroll", onScroll);
}, []);
但是,
event.target
不能在没有编译错误的情况下进行访问。我检查了以下函数调用(如果它在浏览器中工作-忽略错误):
useEffect(() => {
const onScroll = (event: Event) => {
console.log(
"event",
event?.target?.activeElement.getBoundingClientRect() // <--- this function call is actually working (ts-ignored it), even if TypeScript throws an error
window.addEventListener("scroll", onScroll);
return () => window.removeEventListener("scroll", onScroll);
}, []);
抛出
TypeScript error in /home/sirhennihau/Workspace/giphy-search/src/Components/grid.tsx(27,24):
Property 'activeElement' does not exist on type 'EventTarget'. TS2339
25 | console.log(
26 | "event",
> 27 | event?.target?.activeElement.getBoundingClientRect()
| ^
28 | );
29 | };
30 |
我的依赖关系:
"@types/node": "^12.0.0",
"@types/react": "^16.9.53",
"@types/react-dom": "^17.0.0",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-scripts": "4.0.1",
"typescript": "^4.0.3"
也许只是打字不好还是我做错了什么?
发布于 2021-01-08 00:22:43
嗯,是的,React -事件和DOM--事件有时不能“很好地”处理彼此,但是有一些处理用例的干净方法(在我的经验中,最重要的是React中的用例):
DOM事件
DOM
window.addEventListener
需要一个DOM-
EventListener
(
(evt: Event): void;
),因此您需要使用DOM-
Event
接口(就像您所做的那样)。
在这里,我向代码中添加了一些类型,以说明以下内容:
useEffect(() => {
const onScroll: EventListener = (event: Event) => { // <-- DOM-EventListener
console.log("event", event.target);
const win: Window = window; // <-- DOM-Window, extends DOM-EventTarget
win.addEventListener("scroll", onScroll);
return () => window.removeEventListener("scroll", onScroll);
}, []);
event.target
event.target
应该是可访问的。我想您的意思是,如果您试图访问
event.target.activeElement
,就会出现错误。
event.target.activeElement
抛出一个错误
,因为
Event
可以是任何事件,
event.target
可以是任何扩展
EventTarget | null
的元素,这不是特定的元素,而且可能没有
activeElement
。
,但是尽管存在TS错误,它仍然可以工作
,因为实际上它是一个具有
.activeElement
的元素。
const onScroll: EventListener = (event: Event) => {
const targetAny: EventTarget | null = event.target; // <-- maybe has no .activeElement
console.log( targetAny.activeElement );
};
如果您确定该元素是什么,则可以 类型断言 特定的元素:
const onScroll: EventListener = (event: Event) => {
const targetDiv: HTMLDocument = event.target as HTMLDocument; // <-- assert DOM-HTMLDocument
console.log("DOM event", targetDiv.activeElement); // <-- activeElement works
};
反应事件
反应类型应与反应元素一起使用.
您的
仍然需要断言
类型的
event.target
才能访问特定元素的属性(这里我使用
.style
),因为
React.SyntheticEvent
的
.target
(扩展
React.BaseSyntheticEvent
)与DOM-
Event
使用的DOM-
EventTarget
完全相同。
明确一点:是的,React也使用了一些DOM类型,所以这里用DOM事件做出反应“很好”。
const onScrollReact: React.EventHandler<React.UIEvent<ReactNode>> = (event: React.UIEvent<React.ReactNode> ) => {
const target: EventTarget = event.target; // <-- React uses the DOM EventTarget
const targetDiv: HTMLDivElement = target as HTMLDivElement; // <-- type assert DOM-HTMLDivElement
console.log("React event", target.style); // <-- throws TS error
console.log("React event", targetDiv.style); // <-- no TS error
return (<div
onScroll={ onScrollReact }
style={{ height: '400px', overflow: 'scroll' }}
![]() |
内向的杯子 · IIS7 win64位操作系统,提示ADODB.Connection 错误 '800a0e7a' 。server.urlencode;server.htmlencode_登录失败:ole error 3 月前 |
![]() |
兴奋的口罩 · 政体学说 - 《中国大百科全书》第三版网络版 1 年前 |