Skip to content

Commit

Permalink
- Fix infinite rerender when values.value is used valueIsNumericStrin…
Browse files Browse the repository at this point in the history
…g not provided. #786
  • Loading branch information
s-yadav committed Sep 3, 2023
1 parent 5565aa8 commit 424c750
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 5 deletions.
4 changes: 2 additions & 2 deletions documentation/v5/docs/props.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ const MAX_LIMIT = 1000;

**default**: false

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`.
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`.

**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).

Expand Down Expand Up @@ -192,7 +192,7 @@ import { PatternFormat } from 'react-number-format';
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.

:::info
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.
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.
:::

```js
Expand Down
4 changes: 2 additions & 2 deletions src/numeric_format.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -371,9 +371,9 @@ export function useNumericFormat<BaseType = InputAttributes>(
let _valueIsNumericString = valueIsNumericString ?? isNumericString(_value, prefix, suffix);

if (!isNil(value)) {
_valueIsNumericString = valueIsNumericString || typeof value === 'number';
_valueIsNumericString = _valueIsNumericString || typeof value === 'number';
} else if (!isNil(defaultValue)) {
_valueIsNumericString = valueIsNumericString || typeof defaultValue === 'number';
_valueIsNumericString = _valueIsNumericString || typeof defaultValue === 'number';
}

const roundIncomingValueToPrecision = (value: string | number | null | undefined) => {
Expand Down
39 changes: 38 additions & 1 deletion test/library/input_numeric_format.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';
import ReactDOM from 'react-dom';

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

it('should not infinite rerender when valueIsNumericString is not set and decimalScale is provided, and values.value is used inside onValueChange #786', async () => {
const ControlledComponent = (props) => {
const [value, setValue] = useState('');
const [renderCount, setRenderCount] = useState(0);

return (
<>
<NumericFormat
value={value}
onValueChange={(values) => {
//return to avoid infinite rerender
if (renderCount > 10) return;
setValue(values.value);
setRenderCount(renderCount + 1);
}}
{...props}
/>
<span data-testid="renderCount">{renderCount}</span>
</>
);
};
const { input, view } = await render(
<ControlledComponent
thousandSeparator={false}
decimalSeparator=","
decimalScale={2}
fixedDecimalScale
/>,
);

simulateNativeKeyInput(input, '2', 0, 0);

const renderCount = await view.getByTestId('renderCount');
expect(renderCount.innerHTML).toEqual('1');
expect(input.value).toEqual('2,00');
});

describe('should allow typing number if prefix or suffix is just an number #691', () => {
it('when prefix is number', async () => {
const { input } = await render(<NumericFormat prefix="1" />);
Expand Down

0 comments on commit 424c750

Please sign in to comment.