React Number Format
react-number-format is a React component library designed for formatting numeric and pattern-based input fields, as well as displaying formatted text. It provides functionalities for adding prefixes, suffixes, and thousands separators, alongside comprehensive input masking capabilities for various patterns like credit card numbers or phone numbers. The library is currently stable at version 5.4.5 and is actively maintained with frequent bug fix releases, supporting a wide range of React versions up to 19. Its key differentiators include a sophisticated caret engine that handles complex formatting scenarios, custom pattern formatting, and the ability to define custom formatting handlers, offering a high degree of customization for user input experiences. The project emphasizes robust handling of user input while ensuring display consistency.
Common errors
-
Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate.
cause Often occurs when `onValueChange` handler triggers a state update that causes a re-render, and the component's internal logic re-triggers `onValueChange` in a loop, or when `valueIsNumericString` is not provided correctly.fixFor versions prior to v5.3.1, this could be related to `valueIsNumericString` not being provided when `values.value` is used. Ensure your `onValueChange` callback manages state correctly without causing infinite loops. Check for strict equality in dependency arrays for `useEffect` if used. -
Uncaught ReferenceError: require is not defined
cause Attempting to use CommonJS `require()` syntax in an ECMAScript Module (ESM) environment (e.g., modern Create React App, Vite, or Node.js with type: 'module').fixChange `const { Name } = require('react-number-format');` to `import { Name } from 'react-number-format';`. -
defaultValue not triggering onValueChange
cause Prior to v5.4.5, using `defaultValue` prop might not consistently trigger the `onValueChange` callback upon initial render or certain interactions.fixUpgrade to `react-number-format` version `5.4.5` or newer. If you need to programmatically set the initial value and ensure `onValueChange` fires, use the `value` prop with `useState` and manually set the initial state.
Warnings
- breaking Major breaking changes occurred when migrating from v4 to v5. Many props were renamed or removed, and the primary components (e.g., `NumberFormat`) were split into `NumericFormat` and `PatternFormat`. Review the official migration guide.
- breaking The `isCharacterSame` prop was removed from `NumericFormat` and `PatternFormat` (it remains on `NumberFormatBase` for internal use only). Direct usage of this prop on these components will result in an error or undefined behavior.
- gotcha Frequent bug reports and fixes around caret positioning, especially with complex formatting, custom separators, or specific input sequences. While many fixes are applied in patch releases, unusual interactions might still occur.
Install
-
npm install react-number-format -
yarn add react-number-format -
pnpm add react-number-format
Imports
- NumericFormat
const NumericFormat = require('react-number-format').NumericFormat;import { NumericFormat } from 'react-number-format'; - PatternFormat
const PatternFormat = require('react-number-format').PatternFormat;import { PatternFormat } from 'react-number-format'; - NumberFormatBase
import NumberFormatBase from 'react-number-format';
import { NumberFormatBase } from 'react-number-format';
Quickstart
import React, { useState } from 'react';
import { NumericFormat, PatternFormat } from 'react-number-format';
function MyFormattedInputs() {
const [numericValue, setNumericValue] = useState('');
const [phoneValue, setPhoneValue] = useState('');
return (
<div>
<h2>Numeric Input (Currency)</h2>
<NumericFormat
value={numericValue}
onValueChange={(values) => {
setNumericValue(values.value);
}}
thousandSeparator={true}
prefix={'$'}
decimalScale={2}
fixedDecimalScale
placeholder="Enter amount"
/>
<h2>Phone Number Input</h2>
<PatternFormat
value={phoneValue}
onValueChange={(values) => {
setPhoneValue(values.value);
}}
format="(###) ###-####"
mask="_"
placeholder="(123) 456-7890"
/>
<p>Current Numeric Value: {numericValue}</p>
<p>Current Phone Value: {phoneValue}</p>
</div>
);
}
export default MyFormattedInputs;