Skip to content

Commit 424c750

Browse files
committed
- Fix infinite rerender when values.value is used valueIsNumericString not provided. #786
1 parent 5565aa8 commit 424c750

File tree

3 files changed

+42
-5
lines changed

3 files changed

+42
-5
lines changed

documentation/v5/docs/props.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ const MAX_LIMIT = 1000;
162162

163163
**default**: false
164164

165-
If value is passed as string representation of numbers (unformatted) and number is used in any format props like in prefix or suffix in numeric format and format prop in pattern format then this should be passed as `true`.
165+
If value is passed as string representation of numbers (unformatted) and thousandSeparator is `.` in numeric format or number is used in any format props like in prefix or suffix in numeric format and format prop in pattern format then this should be passed as `true`.
166166

167167
**Note**: Prior to 5.2.0 its was always required to be passed as true when value is passed as string representation of numbers (unformatted).
168168

@@ -192,7 +192,7 @@ import { PatternFormat } from 'react-number-format';
192192
This handler provides access to any values changes in the input field and is triggered only when a prop changes or the user input changes. It provides two arguments namely the [valueObject](quirks#values-object) as the first and the [sourceInfo](quirks#sourceInfo) as the second. The [valueObject](quirks#values-object) parameter contains the `formattedValue`, `value` and the `floatValue` of the given input field. The [sourceInfo](quirks#sourceInfo) contains the `event` Object and a `source` key which indicates whether the triggered change is due to an event or a prop change. This is particularly useful in identify whether the change is user driven or is an uncontrolled change due to any prop value being updated.
193193

194194
:::info
195-
If you are using `values.value` which is non formatted value as numeric string. Make sure to pass valueIsNumericString to be true if any of the format prop has number on it. See [valueIsNumericString](#valueisnumericstring-boolean) for more details.
195+
If you are using `values.value` which is non formatted value as numeric string. Make sure to pass valueIsNumericString to be true if any of the format prop has number on it, or if thousandSeparator is `.` in NumericFormat . See [valueIsNumericString](#valueisnumericstring-boolean) for more details.
196196
:::
197197

198198
```js

src/numeric_format.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -371,9 +371,9 @@ export function useNumericFormat<BaseType = InputAttributes>(
371371
let _valueIsNumericString = valueIsNumericString ?? isNumericString(_value, prefix, suffix);
372372

373373
if (!isNil(value)) {
374-
_valueIsNumericString = valueIsNumericString || typeof value === 'number';
374+
_valueIsNumericString = _valueIsNumericString || typeof value === 'number';
375375
} else if (!isNil(defaultValue)) {
376-
_valueIsNumericString = valueIsNumericString || typeof defaultValue === 'number';
376+
_valueIsNumericString = _valueIsNumericString || typeof defaultValue === 'number';
377377
}
378378

379379
const roundIncomingValueToPrecision = (value: string | number | null | undefined) => {

test/library/input_numeric_format.spec.js

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import React, { useState } from 'react';
22
import ReactDOM from 'react-dom';
33

44
import NumericFormat from '../../src/numeric_format';
@@ -694,6 +694,43 @@ describe('Test NumberFormat as input with numeric format options', () => {
694694
expect(input.value).toEqual('12,345');
695695
});
696696

697+
it('should not infinite rerender when valueIsNumericString is not set and decimalScale is provided, and values.value is used inside onValueChange #786', async () => {
698+
const ControlledComponent = (props) => {
699+
const [value, setValue] = useState('');
700+
const [renderCount, setRenderCount] = useState(0);
701+
702+
return (
703+
<>
704+
<NumericFormat
705+
value={value}
706+
onValueChange={(values) => {
707+
//return to avoid infinite rerender
708+
if (renderCount > 10) return;
709+
setValue(values.value);
710+
setRenderCount(renderCount + 1);
711+
}}
712+
{...props}
713+
/>
714+
<span data-testid="renderCount">{renderCount}</span>
715+
</>
716+
);
717+
};
718+
const { input, view } = await render(
719+
<ControlledComponent
720+
thousandSeparator={false}
721+
decimalSeparator=","
722+
decimalScale={2}
723+
fixedDecimalScale
724+
/>,
725+
);
726+
727+
simulateNativeKeyInput(input, '2', 0, 0);
728+
729+
const renderCount = await view.getByTestId('renderCount');
730+
expect(renderCount.innerHTML).toEqual('1');
731+
expect(input.value).toEqual('2,00');
732+
});
733+
697734
describe('should allow typing number if prefix or suffix is just an number #691', () => {
698735
it('when prefix is number', async () => {
699736
const { input } = await render(<NumericFormat prefix="1" />);

0 commit comments

Comments
 (0)