Home > Mobile >  How to avoid object is possibly null with userRef hook
How to avoid object is possibly null with userRef hook

Time:05-20

I use useRef hook

const secondaryCursor = React.useRef(null);

and use it into useEffect later:

positionRef.current.mouseY = mouseY - secondaryCursor.current.clientHeight / 2; //secondaryCursor.current -> TS2531: Object is possibly 'null'

CodePudding user response:

The "Object is possibly null" error is caused because the useRef() hook can be passed an initial value as an argument and we're passing it null as an initial value.

Updated your code as follows if you are sure it won't be null.

positionRef.current.mouseY = mouseY - secondaryCursor.current!.clientHeight / 2;

This link contains many other ways to do so.

Refer: https://bobbyhadz.com/blog/react-useref-object-is-possibly-null#:~:text=The "Object is possibly null" error is caused because the,initialized to the passed argument.

CodePudding user response:

The ref's current property will be null until/unless it's set. In your case, you're using it in a useEffect callback, so assuming you've used the ref on an element that was rendered, it won't be null when you try to use it. But TypeScript doesn't know that, so it warns you of this possible error.

There are (at least) three ways to deal with it, each with pros and cons:

  1. Don't try to use it if it's null (for instance, using an if).

    if (positionRef.current && secondaryCursor.current) {
        positionRef.current.mouseY = mouseY - secondaryCursor.current.clientHeight / 2;
    }
    

    If it's null when the code runs, the code won't do anything. If you were sure it wouldn't be null when this code ran, silently not doing anything may be hard to debug. But if you're not sure whether it will be set, you'd use a guard like that to avoid using it if it isn't.

  2. If you're sure it can't be null, use an assertion function to assert that (with a runtime check so that you get an informative error if the assertion is incorrect):

    assertNotNullish(positionRef.current);
    assertNotNullish(secondaryCursor.current);
    positionRef.current.mouseY = mouseY - secondaryCursor.current.clientHeight / 2;
    

    ...where assertNotNullish is a utility function like this:

    function assertNotNullish<T>(value: T | null | undefined): asserts value is T {
        if (value == null) {
            throw new Error(`Expected non-nullish value, got ${String(value)}`);
        }
    }
    

    The only downside here is that if you're sure it won't be null, you're running a very very very quick test unnecessarily.

  3. If you're sure it can't be null, use the not-nullish assertion type operator (a postfix !).

    positionRef.current!.mouseY = mouseY - secondaryCursor.current!.clientHeight / 2;
    // −−−−−−−−−−−−−−−−^−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^
    

    There's no runtime aspect to that at all, you're just telling TypeScript you know it won't be null. If the assertion is wrong, you'll still get an error at runtime, but it won't be as clear as it would be with #2.

  • Related