我在 React 中有这个事件监听器:
document.removeEventListener("mouseup", this.handleDocumentClick);
这是根据 Flow's source code 对该方法的定义之一:
removeEventListener(type: MouseEventTypes, listener: MouseEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture): void;
似乎监听器必须是 MouseEventListener
类型:
type MouseEventHandler = (event: MouseEvent) => mixed
type MouseEventListener = {handleEvent: MouseEventHandler} | MouseEventHandler
看来我可以这样输入:
handleDocumentClick = (evt: MouseEvent) => {
}
到目前为止,没有流错误。现在,我想检查事件的目标是否在我存储在 React Ref 中的另一个 DOM 节点内。 :
$menu: React.ElementRef<typeof Menu>;
handleDocumentClick = (evt: MouseEvent) => {
if (this.$menu !== null) {
const menu = ReactDOM.findDOMNode(this.$menu);
if (menu) {
console.log(menu.contains(evt.currentTarget));
}
}
}
我得到这个错误:
54: console.log(menu.contains(evt.currentTarget));
^^^^^^^^^^^^^^^^^ EventTarget. This type is incompatible with the expected param type of
447: contains(other: ?Node): boolean;
^^^^ Node. See lib: /private/tmp/flow/flowlib_3e761601/dom.js:447
contains
方法应该适用于事件的目标(即 DOM 节点)。这里可能有什么问题——也许是 Flow 中 contains
的定义?
最佳答案
您有几个选择,其中最简单的可能是:
handleDocumentClick = (evt: MouseEvent) => {
if (this.$menu !== null) {
const menu = ReactDOM.findDOMNode(this.$menu);
if (menu && evt.currentTarget instanceof Node) {
console.log(menu.contains(evt.currentTarget));
}
}
}
但您始终可以转换currentTarget
(您可以转换为Node
,但您需要先转换为any
):
handleDocumentClick = (evt: MouseEvent) => {
if (this.$menu !== null) {
const menu = findDOMNode(this.$menu)
if (menu) {
// console.log(menu.contains(((evt.currentTarget: any): Node)))
console.log(menu.contains((evt.currentTarget: any)))
}
}
}
第一个选项将在您最终遇到一些奇怪的边缘情况时提供保护(并且您始终可以添加实用函数,如 isNode
或重复使用的东西)。
关于javascript - React Flowtype Node.contains() 事件目标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48433096/