【问题标题】:React Flowtype Node.contains() Event TargetReact Flowtype Node.contains() 事件目标
【发布时间】:2018-07-04 02:59:57
【问题描述】:

我在 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 的定义?

【问题讨论】:

    标签: javascript reactjs flowtype


    【解决方案1】:

    你有几个选择,其中最简单的可能就是:

    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 或重复使用的东西)。

    【讨论】:

      【解决方案2】:

      属性currentTarget继承自Event,可以引用Node以外的类型。

      【讨论】:

        猜你喜欢
        • 2018-09-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-16
        • 2019-01-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多