Search code examples
javascriptreactjsreact-ref

Not getting ref value in custom input component


I do have a parent custom component which I can't edit and I am using code like this.

<MyInput>//library component or component i will use in my main component

import * as React from "react";

type Props = {
    value: string | null | undefined;
    label?: string | React.ReactNode;
    autofocus?:boolean
    ref?: React.RefObject<HTMLInputElement>
};

declare class MyInput extends React.Component<Props> {
    static defaultProps: {
        type: string;
    };
    handleFocus: () => void;
    render(): React.JSX.Element;
}

export { MyInput };

And in my main component I am trying to use

function componentA(props: Props) {
  const ref = React.useRef<HTMLInputElement>(null);

  return (
     <MyInput
       max={255}
       autofocus={true}
       ref={ref}
       onFocus={() => ref?.current?.select()}
       value={name}
       onChange={setName}
       placeholder={"sample Name"}
     />

2 problem am facing - First one is
I am getting type error in ref like this

No overload matches this call.
  Overload 1 of 2, '(props: Props | Readonly<Props>): Input', gave the following error.
    Type 'RefObject<HTMLInputElement>' is not assignable to type '(LegacyRef<Input> & RefObject<HTMLInputElement>) | undefined'.
      Type 'RefObject<HTMLInputElement>' is not assignable to type 'RefObject<Input> & RefObject<HTMLInputElement>'.
        Type 'RefObject<HTMLInputElement>' is not assignable to type 'RefObject<Input>'.

and the second issue is I am not getting the reference to the input element?


Solution

  • React protects child nodes from being exposed via references passed from parent through props. Use forwardRef to explicitly expose it:

    type Props = {
      // ... as normal
    };
    
    export const MyInput = forwardRef<HTMLInputElement, Props>(
      ({}, ref) => (
        <input ref={ref}/>
      )
    );
    
    
    function componentA(props: Props) {
      const ref = React.useRef<HTMLInputElement>(null);
    
      return (
         <MyInput ref={ref} />
      );
    }