react-number-format: Changing value and suffix at the same time causes Maximum update depth exceeded error

I’m using react-number-format in combination with Formik and material-ui. I have a use case when I need to call Formiks resetForm and it updates value and a suffix at the same time. E.g. (100 m to 0 ft ).

const NumberFormatCustom = (props: *): NumberFormat => { const { inputRef, onChange, unit, ...other } = props; return ( <NumberFormat {...other} getInputRef={inputRef} onValueChange={values => { onChange({ target: { value: values.value, name: other.name, }, }); }} suffix={unit} /> ); };

NumberFormat is passed though InputProps to TextField.

InputProps={{ inputComponent: NumberFormatCustom }}

This is the console log that shows Maximum update depth exceeded error.

screen shot 2019-01-30 at 5 15 00 pm

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 2
  • Comments: 19 (5 by maintainers)

Commits related to this issue

Most upvoted comments

I think the problem comes from L134 in <NumberFormat>: https://github.com/s-yadav/react-number-format/blob/81ef1cfe38cd06b50e1e9753ff956abefead4da4/src/number_format.js#L134

When a component is re-rendered, the props and prevProps will not be the same instance, so this expression will always be true?

I’ve noticed a situation when a user types really fast, there is a chance that this component gets re-rendered (for any reason):

  • after it calls setState() inside updateValue() (triggered from onChange), but
  • before the setState() callback is called (so a ancestor component gets notified of new value)

And thus the component is rendered with old value when it’s controlled, and it always override its state even when the value in state is actually newer.

After that the callback is finally fired, bringing value to its ancestor component, and triggered another re-render. In my case this is where the whole thing goes into an infinite loop.

I think I found a workaround by using

value={this.state.value || undefined}

This briefly switches the component to uncontrolled if there’s now valid input and breaks the infinite loop.

@rykon I did the same few days ago and it helps. Thank you. But still, it should be fixed in react-number-format.

I was getting something similar – “Maximum update depth…” message when a phone number field was autofilled by Chrome.

I updated the onValueChange() function to check for the existence of the values object as well as the values.formattedValue key before calling onChange. This appears to have solved my problem. Hope this helps.

@MatteoGauthier @antipopp you must set the isNumericString as true and handle the change on onValueChange appropriately. Please, have a look at this codesandbox example with react-hook-form. You can adapt this to Formik/whatever-controller-you-use.

Cheers!

Using 4.4.1v

Don’t know if it’s in fact the same reason or problem, but im having an issue about infinite loop in my component that uses NumberFormat. If you type anything on the field, you got stuckin a loop that re-render with a new value, as if im pressing 0 on my keyboard.

You can check the demo here I have commented all the other custom things that i use in my project and the code only has the INTL format for start the decimal from right to left(as was discussed on #366).

Just try to type any number in the Decimal input field.

However, if you change the decimalLimit to 2 in my Decimal component you will see that code doesn’t break anymore. In fact i need the decimalLimit with 5.

Note: my decmialLimit prop works exaclty as decimalScale from NumberFormat.

Any workaround or problable fix? Do i need to create another issue post for this issue?