I'm making a Datepicker with React and Typescript, and I can't seem to get over the errors with useRef
and the ref's .current
property. I'm trying to get the div
I'm assigning the ref to to close when the document is clicked outside of it.
I just can't quite seem to figure out what I'm doing wrong. Here is my code:
function Datepicker({label, placeholder}: DatepickerProps){
const [open, setOpen] = React.useState(false)
const [day, setDay] = React.useState(0)
const [month, setMonth] = React.useState(new Date().getMonth())
const [year, setYear] = React.useState(new Date().getFullYear())
const picker = React.useRef(null) as HTMLElement | null
React.useEffect(() => {
document.addEventListener("mousedown", toggle)
return () => {
document.removeEventListener("mousedown", toggle)
};
}, []);
const toggle = (e: MouseEvent) => {
if (picker && picker.current){
if (picker.current.contains(e.target) === false){
setOpen(false)
}
}
}
//...
return(
//...
<div
ref={picker}
className={"datepicker-picker" + (open ? " open" : "")}
>
//...
)
}
React.useRef(null) as HTMLElement | null
is giving me the following problem:
Conversion of type 'MutableRefObject<null>' to type 'HTMLElement' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
Type 'MutableRefObject<null>' is missing the following properties from type 'HTMLElement': accessKey, accessKeyLabel, autocapitalize, dir, and 234 more.ts(2352)
.current
is giving me the following:
Property 'current' does not exist on type 'HTMLElement'.
and when I try to apply the ref to a div
element, its says the following:
Type 'HTMLElement | null' is not assignable to type 'string | ((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined'.
Type 'HTMLElement' is not assignable to type 'string | ((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined'.
Type 'HTMLElement' is not assignable to type 'string'.ts(2322)
index.d.ts(143, 9): The expected type comes from property 'ref' which is declared here on type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'
I'm using VSCode as my IDE, if that helps at all.
To use useRef with TypeScript, it is actually pretty easy, all you need to do is provide the type that you want to the function via open and closed chevrons like you would with other React hooks like so: const myRef = useRef<number>(0) .
The error "Property 'X' does not exist on type 'HTMLElement'" occurs when we try to access a property that doesn't exist on an element of type HTMLElement . To solve the error, use a type assertion to type the element correctly before accessing the property.
The error "Property does not exist on type 'never'" occurs when we forget to type a state array or don't type the return value of the useRef hook. To solve the error, use a generic to explicitly type the state array or the ref value in your React application.
useRef
does not return the value in the ref - typing the return value as HTMLElement | null
is inaccurate. Use a generic argument instead:
const picker = React.useRef<HTMLElement>(null);
You'll also need to change toggle
so that the type narrowing occurs as desired:
const toggle = (e: MouseEvent) => {
const { current } = picker;
if (current && !current.contains(e.target)) {
setOpen(false);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With