Sharing refs between react-imask, react-bootstrap, and react-hook-form

1.5k Views Asked by At

I'm currently using react-bootstrap and react-imask together using their example with IMaskMixin:

import { IMaskMixin } from 'react-imask';
import { FormControl } from 'react-bootstrap';

const MaskedFormControl = IMaskMixin(({inputRef, ...props}) => (
  <FormControl
    {...props}
    ref={inputRef} 
  />
));

Now, I would like to use react-hook-form with this control;

const { register } = useForm();
<MaskedFormControl {...register('name')} />

The spread on the register function is the equivalent of this

const { onChange, onBlur, name, ref } = register('name');

So it is expecting the ref to access the input ref, the values in react-hook-form never get set with what is typed in the input.

I use MasedFormControl in places I dont' use react-hook-form so I would like to make it work with or without react-hook-form.

How do I make this work?

1

There are 1 best solutions below

1
On

Not in particular for Bootstrap, but I'll show general idea on how to integrate react-imask, react-hook-form with any kind of input:

  1. Define schema
  const schema = yup.object({
    phone: yup
      .string()
      .required('Phone is required')
      .length(10, 'Phone must contain 10 digits'),
  });
  1. Declare form
  const { control, handleSubmit } = useForm({
    resolver: yupResolver(schema),
    mode: 'onTouched',
    defaultValues: {
      phone: "4437787349",
    },
  });
  1. Add imask
  const mask = useIMask({
    mask: '(000) 000-00-00',
  });
  1. Render input component
  <Controller
    render={(params) => (
      <input
        name={params.field.name}
        onBlur={params.field.onBlur}
        defaultValue={params.field.value}
        ref={mask.ref}
        onChange={() =>
          params.field.onChange({
            target: { value: mask.unmaskedValue },
          })
        }
        placeholder="Phone number"
      />
      // show error messages
      // <p>{params.fieldState.error?.message}</p>
    )}
    name="phone"
    control={control}
  />