react-number-format icon indicating copy to clipboard operation
react-number-format copied to clipboard

NumericFormat does not accept ref prop

Open vitorbertolucci opened this issue 2 years ago • 5 comments

Describe the issue and the actual behavior

The NumericFormat component does not accept a ref prop on v5, but the former default ReactNumberFormat component did.

Describe the expected behavior

I would like to be able to use a ref so I can use NumericFormat as an uncontrolled component. I used to do this with ReactNumberFormat so I did not need to use onValueChange function nor pass the value prop. And I used the ref so I could retrieve the input value and also clear it when needed.

Here is the error when I try to pass a ref to NumericFormat:

Property 'ref' does not exist on type 'IntrinsicAttributes & InternalNumberFormatBase & { thousandSeparator?: string | boolean | undefined; decimalSeparator?: string | undefined; ... 7 more ...; prefix?: string | undefined; } & Omit<...> & Omit<...> & { ...; }'

vitorbertolucci avatar Oct 14 '22 18:10 vitorbertolucci

is getInputRef prop not working for you? https://s-yadav.github.io/react-number-format/docs/props#getinputref-elm--void

s-yadav avatar Oct 25 '22 14:10 s-yadav

is getInputRef prop not working for you? https://s-yadav.github.io/react-number-format/docs/props#getinputref-elm--void

getInputRef gives a ref for the actual <input> element. I'd like to have a ref to NumericFormat component so I can read its entire state.

I have already come up with an obvious workaround, which is to wrap the NumericFormat in my own custom input component and use it as a controlled component, but until v5 it was possible to get a ref to ReactNumberFormat and use it as an uncontrolled component.

vitorbertolucci avatar Oct 25 '22 14:10 vitorbertolucci

Ohh its a functional component now, so you can’t get the internal state now. Btw, whats the usecase of getting internal values. If you require more fine grained control on the behaviour, you may use the hook useNumericFormat. You can refer the customisation doc. https://s-yadav.github.io/react-number-format/docs/customization

s-yadav avatar Oct 25 '22 15:10 s-yadav

Just spent too long struggling to make this play nice with react-hook-form in a Controller. I was getting this warning using NumericFormat inside the Controllers render

Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

Thanks @vitorbertolucci for mentioning the workaround which was unfortunately not so obvious to me. Here is how I got it working in case other people need it

const NumericFormatWrapper = React.forwardRef(({ id, ...rest }, ref) => {
  return (
    <NumericFormat
      id={id}
      getInputRef={ref}
      {...rest}
      className="<tailwind classes>"
    />
  );
});

You can also make your own custom input component and pass that to NumericFormat if you want, the hard part was realizing NumericFormat needed a wrapper to make it work as expected.

Also in case it's useful for others, here is how I'm using it inside a react hook form controller

const id = useId();
...
        <Controller
          name={formName}
          control={control}
          render={({ field }) => <NumericFormatWrapper id={id} {...field} {...rest} />}
        />

DavidJayBrady avatar Mar 20 '24 21:03 DavidJayBrady

or maybe you can just exclude ref from field.

 <Controller
        name={name}
        control={control}
        render={({ field }) => {
        const { ref: _, ...restField } = field 
        return (
            <NumericFormat
              {...restField}
              {...props}
              getInputRef={ref}
              maxLength={7}
              customInput={Input}
              customSuffix={customSuffix}
            />
          )
        }}
      />

tygas avatar Sep 19 '24 17:09 tygas