Can't access forwareded Ref value in parent component React typescript

Viewed 215

I have a situation where i have created a component for input. This is a custom component and i want to access the value entered by user in this input in the parent component(where i am using it).

I am forwarding ref from this Input Component but the parent component is receiving the complete input not the value. How can i use the value. Below is my code.

Input.tsx

  interface AuxProps {
      id :''
    }

const Input = React.forwardRef<HTMLInputElement,AuxProps>((props, ref) => {
  return (      
      <input 
      id={props.id}   
      ref = {ref}         
      defaultValue = '1' 
      type='number' 
      ></input>
  );
});
export default Input;

HeaderComponent.tsx

const HeaderComponent= () => {

  const inputAmount = useRef<HTMLInputElement>(null);
  const addProductHandle = (event: any) => {
    event.preventDefault();
    console.log(inputAmount.current.value);     //<----Error:- object is possibly null
  };
  return (
    <form className={classes["form"]}>
      <Input id="1s" ref={inputAmount}></Input>
      <button onClick={addProductHandle}> + ADD </button>
    </form>
  );
};
export default HeaderComponent;

Not sure how can i use this ref value.

1 Answers

You were close.

Let's take a look on useRef return type:

  interface RefObject<T> {
        readonly current: T | null;
    }

According to this type signature, current property might be T (in our case HTMLInputElement) or null.

This is why you are using typescript - to avoid errors on PROD.

Since current might be null, TS asks you to double check if current exists.

you can add ? or if condition:

import React, { useRef, MouseEventHandler } from 'react'

interface AuxProps {
    id: string
}

const Input = React.forwardRef<HTMLInputElement, AuxProps>((props, ref) => {
    return (
        <input
            id={props.id}
            ref={ref}
            defaultValue='1'
            type='number'
        ></input>
    );
});


const HeaderComponent = () => {

    const inputAmount = useRef<HTMLInputElement>(null);
    const addProductHandle: MouseEventHandler<HTMLButtonElement> = (event) => {

        event.preventDefault();
        console.log(inputAmount.current?.value);     // ok 
        if (inputAmount.current) {
            console.log(inputAmount.current.value); //ok
        }
    };
    return (
        <form >
            <Input id="1s" ref={inputAmount}></Input>
            <button onClick={addProductHandle}> + ADD </button>
        </form>
    );
};
export default HeaderComponent;

Btw, you can use MouseEventHandler<HTMLButtonElement> for click handlers. See my example

Related