React Masked Input Component
react-maskedinput is a React component designed to facilitate masked input fields, enabling developers to enforce specific input patterns for data like phone numbers, dates, or credit card numbers. It is built on top of the `inputmask-core` library for its core masking logic. The current stable version is 4.0.1, released in January 2018. Due to its age and the last release date, the project's release cadence is irregular and it appears to be largely unmaintained. Key features include support for custom format characters and controlled component behavior through the `value` prop. A significant note from the author indicates, "This project has never been used by its author, other than while making it," which might suggest limited real-world testing or ongoing support. Developers should consider its age and potential compatibility issues with modern React versions and ecosystems.
Common errors
-
Warning: MaskedInput: `React.createClass` is deprecated and will be removed in a future version of React. Use JavaScript classes instead.
cause Using an older version of React that relies on `createClass` while `react-maskedinput` v4.0.0+ expects modern React class components, or your build setup is incompatible.fixEnsure your React project is on a version compatible with `React.Component` (React 0.14.9, 15.3.0, or 16.x) and that your build tools correctly transpile JavaScript classes. -
Invalid prop `pattern` supplied to `MaskedInput`. Expected `string`.
cause Attempting to use the deprecated `pattern` prop instead of `mask` for defining the input mask.fixChange the prop name from `pattern` to `mask` for your input masking definition. For example, `mask="1111"` instead of `pattern="1111"`. -
TypeError: Cannot read properties of undefined (reading 'value') in custom onChange handler (or similar error related to event.target.value)
cause The `MaskedInput` component's `onChange` behavior is non-standard; it doesn't always provide a `SyntheticEvent` with a `target` property directly mirroring a native input. It calls your handler with an event-like object where `e.target` refers to the input element itself.fixEnsure your `onChange` handler correctly accesses `e.target.value` or `e.target.name` (as shown in the quickstart), understanding that the `e` object might not be a full `SyntheticEvent`.
Warnings
- breaking In v4.0.0, the package transitioned from `React.createClass` to `React.Component` and from `React.PropTypes` to the `prop-types` package. This requires React 0.14.9, 15.3.0, or 16.x and might break older applications using `createClass`.
- breaking Version 3.0.0 introduced a significant breaking change: the `pattern` prop was renamed to `mask` to avoid conflicts with the HTML5 `pattern` attribute.
- breaking Version 3.0.0 raised the minimum required React version to 0.14.
- gotcha The `onChange` callback on `MaskedInput` is called directly by the component and does not generate a standard React `SyntheticEvent` that would bubble up like a regular `<input>`. You *must* pass an `onChange` prop to retrieve the input's value.
- gotcha The package includes a badge stating, 'This project has never been used by its author, other than while making it.' This suggests a potential lack of real-world testing and ongoing support from the original author, which could impact stability or maintenance.
- gotcha The project's last update was in early 2018. This makes it potentially incompatible with newer React features, APIs, and the broader JavaScript ecosystem, including modern build tools and TypeScript versions, and may contain unpatched security vulnerabilities.
Install
-
npm install react-maskedinput -
yarn add react-maskedinput -
pnpm add react-maskedinput
Imports
- MaskedInput
const MaskedInput = require('react-maskedinput')import MaskedInput from 'react-maskedinput'
- MaskedInput
import { MaskedInput } from 'react-maskedinput'import MaskedInput from 'react-maskedinput'
Quickstart
import React from 'react';
import MaskedInput from 'react-maskedinput';
class CreditCardDetails extends React.Component {
state = {
card: '',
expiry: '',
ccv: ''
};
_onChange = (e) => {
this.setState({ [e.target.name]: e.target.value });
};
render() {
return (
<div className="CreditCardDetails">
<label>
Card Number:{' '}
<MaskedInput mask="1111 1111 1111 1111" name="card" size="20" onChange={this._onChange} />
</label>
<label>
Expiry Date:{' '}
<MaskedInput mask="11/1111" name="expiry" placeholder="mm/yyyy" onChange={this._onChange} />
</label>
<label>
CCV:{' '}
<MaskedInput mask="111" name="ccv" onChange={this._onChange} />
</label>
</div>
);
}
}
// Example of a custom masked input wrapper
function CustomAlphaNumericInput(props) {
return (
<MaskedInput
mask="AAAA-1111"
placeholder="ABCD-1234"
size="10"
{...props}
formatCharacters={{
'A': {
validate(char) { return /[a-zA-Z]/.test(char) },
transform(char) { return char.toUpperCase() }
}
}}
/>
);
}
export default CreditCardDetails;