无法将 RefObject<HTMLDivElement> 分配给 RefObject<HTMLElement> 实例

Mik*_*hke 14 typescript reactjs

在 React 组件中,我想保留对类型不同(div、img 等)的子节点的引用。所以我定义了一个成员变量:

export class MyComp extends Component<IProperties, IState> {

    private triggerRef = React.createRef<HTMLElement>();

...
}

Run Code Online (Sandbox Code Playgroud)

并想用它来保存所需的参考:

    const trigger = <div ref={this.triggerRef} className={className} style={style} />;
Run Code Online (Sandbox Code Playgroud)

虽然,这会产生一个错误:

Type 'RefObject<HTMLElement>' is not assignable to type 'string | ((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined'.
  Type 'RefObject<HTMLElement>' is not assignable to type 'RefObject<HTMLDivElement>'.
    Property 'align' is missing in type 'HTMLElement' but required in type 'HTMLDivElement'.ts(2322)
lib.dom.d.ts(6708, 5): 'align' is declared here.
index.d.ts(143, 9): The expected type comes from property 'ref' which is declared here on type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'
Run Code Online (Sandbox Code Playgroud)

该行Type 'RefObject<HTMLElement>' is not assignable to type 'RefObject<HTMLDivElement>'表示两个 ref 对象类型不兼容,即使HTMLDivElementextends HTMLElement。我希望 ref 类型是赋值兼容的,因为它们显然有重叠。

在不更改要使用的成员变量的情况下,这里的正确方法是什么HTMLDivElement

Vet*_*ack 18

对于所有因为在编写自定义钩子用 DOM 元素做某事时遇到这个问题而来到这个线程的人,以下工作:

function useMyCustomHook<T extends HTMLElement>{
    const myRef = useRef<T>(null)

    // do something with the ref, e.g. adding event listeners

    return {ref: myRef}
}

function MyComponent(){
    const {ref: myElementRef} = useMyCustomHook<HTMLDivElement>()

    return <div ref={myElementRef}>A Div</div>
}
Run Code Online (Sandbox Code Playgroud)


Mik*_*hke 14

这并不是我原来问题的真正答案,而是一个简单的解决方法:

const trigger = <div 
    ref={this.triggerRef as React.RefObject<HTMLDivElement>}
    className={className}
    style={style}
/>
Run Code Online (Sandbox Code Playgroud)

但它很好地完成了这项工作。


vox*_*oid 5

改变

private triggerRef = React.createRef<HTMLElement>();
Run Code Online (Sandbox Code Playgroud)

到特定的元素类型:

private triggerRef = React.createRef<HTMLDivElement>();`
Run Code Online (Sandbox Code Playgroud)

然后就ref={this.triggerRef}可以工作了(不需要像这样进行转换ref={this.triggerRef as React.RefObject<HTMLDivElement>})。