Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Warning with function components cannot be given refs - even though using forwardRef() with Styled Components

I am receiving the warning Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?. I'm confused because I am using forwardRef()... and it is working.

I'm attempting to pass my custom Input Element to ReactDatePicker. There are several GitHub issues on this such as this one. But I can't work through this last error while implementing the examples on there that work.

Here is the custom Input element:

interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
  ref?: React.Ref<HTMLInputElement>;
}

const StyledInput = styled.input<InputProps>`
  box-sizing: border-box;
  // ...
`;

export const Input: FunctionComponent<InputProps> = (props: InputProps) => {
  return (
    <>
      <StyledInput {...props}></StyledInput>
    </>
  );
};

And here is the custom DatePicker with ReactDatePicker where the error occurs:

interface DatePickerProps extends ReactDatePickerProps {
    //... custom props
}

const StyledDatePicker = styled(ReactDatePicker)`
    //... some CSS
`;

const CustomInput = forwardRef<HTMLInputElement>((inputProps, ref) => (
  <Input {...inputProps} ref={ref} /> // <-- error occurs here
));

export const DatePicker: FunctionComponent<DatePickerProps> = (props: DatePickerProps) => {
  const ref = React.createRef<HTMLInputElement>();

  return (
    <>
      <StyledDatePicker
        {...props}
        customInput={<CustomInput ref={ref} />}
      ></StyledDatePicker>
    </>
  );
};
like image 917
Diesel Avatar asked Dec 22 '22 20:12

Diesel


1 Answers

You've created two components, Input, and CustomInput. The latter is implemented using forwardRef, so you can pass a ref into it. The former is not, so passing a ref to it is an error. It looks to me like CustomInput doesn't serve any purpose, so I think what you meant to do is have just one component, which makes use of forwardRef:

export const Input = React.forwardRef((props: InputProps, ref: React.Ref<HtmlInputElement>) => {
  return (
    <>
      <StyledInput {...props} ref={ref}/>
    </>
  )
});

// To be used like:
<StyledDatePicker
  {...props}
  customInput={<Input ref={ref} />}
/>
like image 106
Nicholas Tower Avatar answered Dec 28 '22 17:12

Nicholas Tower