I know there are quiet lot of articles and related questions out there, but I am coming to you looking for help, I am having a hard time typing a custom hook which adds an event listener to the attached window. But I am getting this error.
Property 'current' does not exist on type 'never'.
I have tried many things but nothing seems to work, and my library does not compile. I guess this is related to having the strict flag on.
The function is the following.
import { useEffect, useRef } from "react";
export function usePatientContextListener(handler: Function, element = window) {
const savedHandler = useRef<Function>(null);
useEffect(() => {
savedHandler.current = handler;
}, [handler]);
useEffect(() => {
savedHandler.current = handler;
const isSupported = element && element.addEventListener;
if (!isSupported || savedHandler) return;
const listener = (event: Event) => {
// eslint-disable-next-line no-extra-boolean-cast
if (!!savedHandler?.current) {
savedHandler.current(event)
}
};
window.addEventListener("message", listener, false);
return () => {
window.removeEventListener("message", listener);
};
}, [element]);
}
Also when I pass null as default value, I get another error saying that current is a read-only property. If I remove the null, the error goes away.
Cannot assign to 'current' because it is a read-only property.
I have tried everything and still the error won't go away. I appreciate if you have experienced this or can help me in any way. Last, I attach the error image

It has nothing to do with React.useRef hook. Your code has something wrong. The savedHandler ref will be a React.MutableRefObject which always exists. But you return if it exists, this will make the TS infer the ref has a never type.
Change:
if (!isSupported || savedHandler) return;
To:
if (!isSupported) return;
For example:
function main() {
const ref = { current: null }
if (ref) return;
// TS infer ref has `never` type
if (ref.current) {
ref.current
}
}
Playground Link
The complete code:
function usePatientContextListener(handler: Function, element = window) {
const savedHandler = useRef<Function | null>(null);
useEffect(() => {
savedHandler.current = handler;
}, [handler]);
useEffect(() => {
savedHandler.current = handler;
const isSupported = element && element.addEventListener;
if (!isSupported) return;
const listener = (event: Event) => {
if (savedHandler?.current) {
savedHandler.current(event);
}
};
window.addEventListener('message', listener, false);
return () => {
window.removeEventListener('message', listener);
};
}, [element]);
}
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