GoncharukOrg / react-input

109 stars 9 forks source link

Dynamic mask causes error in `react-hook-form` #29

Closed MrLightful closed 4 months ago

MrLightful commented 4 months ago

Stack: react-hook-form, shadcn-ui.

Based on the changes in a type field, I need to apply different masks to the document field. The default mask works fine. But when switched, I can write 3 digits, and then start getting errors. The last digit changes at the same spot, although expected to go to the next one in mask.

I tried to use modify to change the mask accordingly, but it causes same issue.

Would appreciate help.

Form Field

``` { let mask: string let placeholder: string if (form.getValues('documentType') === 'cpf') { mask = cpfMask placeholder = 'CPF' } else { mask = cnpjMask placeholder = 'CNPJ' } return ( ) }} /> ```

Error

``` Error: An invalid character was found in the initialized property value `value` or `defaultValue` (index: 2). Check the correctness of the initialized value in the specified property. Invalid value: "123". at eval (useMask.js:8:116) at initialValue (useMask.js:8:1493) at init (useMask.js:8:1721) at Object.set (useInput.js:10:1170) at eval (useConnectedInputRef.js:7:97) at commitAttachRef (react-dom.development.js:21677:37) at safelyAttachRef (react-dom.development.js:20803:5) at commitLayoutEffectOnFiber (react-dom.development.js:21498:11) at recursivelyTraverseLayoutEffects (react-dom.development.js:22926:7) at commitLayoutEffectOnFiber (react-dom.development.js:21407:9) ```

MrLightful commented 4 months ago

Seems to be fixed.

I extracted ref from field, so it's not forwarded to InputMask.

Not sure tho if this will have any consequences on form functionality.

<FormField
    control={form.control}
    name="document"
    defaultValue=""
    disabled={
        form.formState.isLoading ||
        form.formState.isSubmitting
    }
    render={({ field: { ref, ...field } }) => {
        const documentType =
            form.getValues('documentType')
        const mask =
            documentType === 'cpf' ? cpfMask : cnpjMask
        const placeholder =
            documentType === 'cpf' ? 'CPF' : 'CNPJ'

        return (
            <FormItem className="grow">
                <FormControl>
                    <InputMask
                        component={Input}
                        mask={mask}
                        replacement={{ x: /\d/ }}
                        placeholder={placeholder}
                        type="text"
                        autoCapitalize="none"
                        autoCorrect="off"
                        {...field}
                    />
                </FormControl>
                <FormMessage />
            </FormItem>
        )
    }}
/>