Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Property current does not exist on type never - React useRef()

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

enter image description here

like image 731
Jhonycage Avatar asked Oct 28 '25 15:10

Jhonycage


1 Answers

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]);
}
like image 86
slideshowp2 Avatar answered Oct 30 '25 07:10

slideshowp2



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!