Home > Net >  Property does not exist on type 'IntrinsicAttributes' with useFormContext and custom tag
Property does not exist on type 'IntrinsicAttributes' with useFormContext and custom tag

Time:12-18

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

  • Related