In my React (w/ typescript) application I've created a form using react-hook-form to manage all the logic of it.
I've then customised the select element with some css and other things. But, for the sake of question's simplicity, here the barebone component:
import { forwardRef } from 'react';
type Props = React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLSelectElement>, HTMLSelectElement>;
const Select = forwardRef<HTMLSelectElement, Props>((props, ref) => {
return (
<select ref={ref} {...props}>
<option value="">...</option>
{props.children}
</select>
);
});
export default Select;
I've then defined another component that "specialise" the previous one, as:
import { forwardRef } from 'react';
import Select from './select';
type Props = React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLSelectElement>, HTMLSelectElement> & { label: string; errors?: string };
const SelectWitLargeData = forwardRef<HTMLSelectElement, Props>((props, ref) => {
return (
<Select ref={ref} {...props}>
...large amount of options
</Select>
);
});
export default SelectWitLargeData;
The problem is that the compiler gives me an error on <Select ref={ref} (<- here) ...>
Type 'ForwardedRef<HTMLSelectElement> | LegacyRef<HTMLSelectElement>' is not assignable to type 'Ref<HTMLSelectElement>'.
Type 'string' is not assignable to type 'Ref<HTMLSelectElement>'.ts(2322)
index.d.ts(140, 9): The expected type comes from property 'ref' which is declared here on
type 'IntrinsicAttributes & Pick<Props, "label" | "key" | keyof InputHTMLAttributes<HTMLSelectElement> | "errors"> & RefAttributes<...>'
(JSX attribute) RefAttributes<HTMLSelectElement>.ref?: Ref<HTMLSelectElement>
I've search for solutions online, and found many suggestions, but none of these work.
Any help is appreciated Thanks in advance!
Edit Here's an example form to consume the components
import { useEffect } from 'react';
import { useForm } from 'react-hook-form';
import Select from '@components/select';
import SelectWithLargeData from '@components/select-with-large-data';
type Form = {
email: string;
state: string;
country: string;
};
const Address: React.FC = () => {
const { handleSubmit, register, setValue } = useForm<Form>();
useEffect(() => {
setValue('state', 'AL');
}, [setValue]);
const onSubmit = async (input: Form) => {
console.log(input);
};
return (
<>
<form onSubmit={handleSubmit(onSubmit)} className="space-y-10">
<input type="email" {...register('email', { required: true })} />
<SelectWithLargeData label="Provincia" {...register('state', { required: true })} />
<Select label="Stato" {...register('country', { required: true })}>
<option value="IT">Italia</option>
</Select>
</form>
</>
);
};
export default Address;
Edit 2 https://codesandbox.io/s/withered-rain-w9ej4