Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ref object is possibly undefined TypeScript React

I have a component that uses a hook to set the input value into component state. I want to add a class when the input value is more than 0 characters in length, however I'm coming across an issue where TypeScript says my ref may be undefined.

I can't get rid of this error even if I check if the ref exists in the conditional that wraps the code to add the class. I'm not sure on the solution to this.

Error: Object is possibly 'undefined' on inputValue.current.classList.add(inputHasContentClassName);

import React, { useState, useEffect, useRef } from 'react';

const Component: React.FC = () => {
  const [inputValue, setInputValue] = useState('');
  const myRef = useRef();

  useEffect(() => {
    const inputHasContentClassName = 'input--has-value';

    if (inputValue.length > 0 && inputValue) {
      inputValue.current.classList.add(inputHasContentClassName);
    } else {
      inputValue.current.classList.remove(inputHasContentClassName);
    }
  }, [inputValue]);

  function handleInputChange(e: React.FormEvent<HTMLInputElement>) {
    setInputValue(e.currentTarget.value);
  }

  function handleSubmit(e: React.FormEvent) {
    e.preventDefault();

    console.log('Submit form');
  }

  return (
    <>
      <section>
        <form onSubmit={handleSubmit}>
          <div>
            <input
              ref={myRef}
              onChange={handleInputChange}
              type="number"
            />
            <label>Input Label</label>
          </div>
          <button
            type="submit"
            disabled={inputValue.length === 0}
          >
            Submit
          </button>
        </form>
      </section>
    </>
  );
};

export default Component;
like image 491
Antfish Avatar asked Jan 24 '20 18:01

Antfish


People also ask

How do I fix object is possibly undefined TypeScript React?

The "Object is possibly 'undefined'" error occurs when we try to access a property on an object that may have a value of undefined . To solve the error, use the optional chaining operator or a type guard to make sure the reference is not undefined before accessing properties.

Why is ref undefined?

If we try to access the current property of the ref directly in the component, we would get undefined back because the ref hasn't been set up and the div element has not been rendered. You can also access the current property of the ref in an event handler function.

How do you prevent undefined in TypeScript?

To avoid undefined values when using or accessing the optional object properties, the basic idea is to check the property value using an if conditional statement or the optional chaining operator before accessing the object property in TypeScript.

What is Mutablerefobject?

This means that whenever there is change in state then all the codes in the functional component is executed. This implies if we have a instance variable inside the functional component then with every render this will be initialized with the default value.


Video Answer


1 Answers

useRef() returns an object with a current property, which contains the object you actually care about. And before the first render is complete, that current property will be null. This means the type of that ref is:

{ current: WhateverTypeYouCareAbout | null }

And that means you have to handle null as a possible value of the current property. But the ref object itself will always exist, it's just that its current property may be null.

I would simply store the current value of your ref in a variable, test that existence, and then use it.

  useEffect(() => {
    const inputHasContentClassName = 'input--has-value';
    const inputElement = inputValue.current;        

    if (inputElement && inputElement.value.length > 0) {
      inputElement.classList.add(inputHasContentClassName);
    } else {
      inputElement.classList.remove(inputHasContentClassName);
    }
  }, [inputValue]);

You can also tell the TypeScript compiler the type of your ref (in this case HTMLInputElement) by doing the following:

const myRef = useRef<HTMLInputElement>();
like image 192
Alex Wayne Avatar answered Sep 20 '22 13:09

Alex Wayne