Reputation: 53337
In a React component I want to keep a reference to a child node which can differ in type (div, img etc.). So I defined a member variable:
export class MyComp extends Component<IProperties, IState> {
private triggerRef = React.createRef<HTMLElement>();
...
}
and want to use that to hold the required ref:
const trigger = <div ref={this.triggerRef} className={className} style={style} />;
Though, this produces an error:
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>'
The line Type 'RefObject<HTMLElement>' is not assignable to type 'RefObject<HTMLDivElement>'
says the two ref object types are incompatible, even though HTMLDivElement
extends HTMLElement
. I'd expect that the ref types are assignment compatible as they clearly have an overlap.
What is the correct approach here, without changing the member variable to use HTMLDivElement
?
Upvotes: 38
Views: 65475
Reputation: 457
This worked for me
const refPanel_1 = useRef<null | HTMLDivElement>(null);
Upvotes: 1
Reputation: 1289
Change
private triggerRef = React.createRef<HTMLElement>();
to the specific element type:
private triggerRef = React.createRef<HTMLDivElement>();`
And then ref={this.triggerRef}
will work (without needing to cast like ref={this.triggerRef as React.RefObject<HTMLDivElement>}
).
Upvotes: 6
Reputation: 53337
This is not really an answer to my original question, but an easy workaround and it does the job nicely:
const trigger = <div
ref={this.triggerRef as React.RefObject<HTMLDivElement>}
className={className}
style={style}
/>
Upvotes: 54
Reputation: 2505
For all people coming to this thread because they encounter this problem when writing a custom hook doing something with a DOM Element, the following works:
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>
}
Upvotes: 37