Recently I changed my custom input components to use react useFormContext
instead of passing errors
and register
components to them via props. Since doing so, I'm encountering this annoying typescript error:
Property 'defaultValue' does not exist on type 'IntrinsicAttributes'
Take this part of the code:
<Tag
type={type}
id={title}
{...register(title)}
defaultValue={defaultValue}
placeholder={placeholder}
disabled={disabled}
/>
It shows the error only under the defaultValue
, but if I remove it, it then decides to show it under the placeholder
, and so on if that's removed.
Also, I've noticed that the problem is imperfectly solved by changing Tag
to input
, which is not good because then I can't use the component for, for example, textarea
inputs. It literally worked before and I've only changed it use form context so no idea why it wouldn't like that.
Does anyone have any ideas why this problem occurs? The relevant part of the form:
const CreatePageForm: FC<CreatePageFormProps> = ({ createPage, setCreatePageModalIsOpen, loadingCreatePage }) => {
const methods = useForm<PageFormInputs>({
resolver: yupResolver(createPageSchema),
mode: 'onTouched',
});
// const { // was like this commented out before, when it worked
// register,
// handleSubmit,
// formState: { errors },
// } = useForm<PageFormInputs>({
// resolver: yupResolver(createPageSchema),
// mode: 'onTouched',
// });
const onSubmit: SubmitHandler<PageFormInputs> = (data) => createPage(data);
return (
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit(onSubmit)}>
<div className={styles.formInner}>
<InputField type='text' title='title' />
<SelectField type='select' title='type' defaultValue=''>
<InputField type='textarea' title='notes' />
...
The component:
interface InputFieldProps {
title: string;
type: string;
defaultValue?: any;
cls?: string;
placeholder?: string;
disabled?: boolean;
}
export const InputField: FC<InputFieldProps> = ({ title, type, defaultValue, cls, placeholder, disabled = false }) => {
const { register } = useFormContext();
const tags: { [key: string]: string } = {
text: 'input',
textarea: 'textarea',
// select: 'select',
};
const Tag = tags[type];
return (
<FieldContainer title={title} cls={cls}>
<Tag
type={type}
id={title}
{...register(title)}
defaultValue={defaultValue}
placeholder={placeholder}
disabled={disabled}
/>
</FieldContainer>
);
};
interface FieldContainerProps {
title: string;
children: ReactNode;
cls?: string;
}
const FieldContainer: FC<FieldContainerProps> = ({ title, cls, children }) => {
const { errors } = useFormState();
return (
<div className={`${styles.inputContainer} ${cls || ''}`}>
<label htmlFor={title}>{capitalise(title)}:</label>
{children}
{errors?.[title] && <span className={styles.required}>{errors?.[title]?.message}</span>}
</div>
);
};
Thanks.
CodePudding user response:
It's not related to react-hook-form. You get that error because <Tag />
is typed as a string. So TypeScript doesn't know it's a react element.
Here is a working example of your code: https://codesandbox.io/s/frosty-bird-uxrb6?file=/src/App.tsx