Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(feat): add react strict mode and remove deprecated lifecycles methods #128

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 64 additions & 62 deletions demo/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,69 +44,71 @@ class App extends React.Component {
}

render() {
return <div className="App">
<h1>
<code>&lt;<a href="https://github.com/insin/react-maskedinput">MaskedInput</a>/&gt;</code>
</h1>
<p className="lead">A React component which creates a masked <code>&lt;input/&gt;</code></p>
<div className="form-field">
<label htmlFor="card">Card Number:</label>
<MaskedInput mask="1111 1111 1111 1111" name="card" id="card" size="20" value={this.state.card} onChange={this._onChange}/>
return (<React.StrictMode>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why add this? I think it'd better for the demo to not have an arbitrary performance block on it

Copy link
Author

@Radu-Dunarentu Radu-Dunarentu Jun 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand how StrictMode is a performance block, care to explain?
Edit: also, having StrictMode warns future developers for potential problems in the application.

Strict mode checks are run in development mode only; they do not impact the production build.

<div className="App">
<h1>
<code>&lt;<a href="https://github.com/insin/react-maskedinput">MaskedInput</a>/&gt;</code>
</h1>
<p className="lead">A React component which creates a masked <code>&lt;input/&gt;</code></p>
<div className="form-field">
<label htmlFor="card">Card Number:</label>
<MaskedInput mask="1111 1111 1111 1111" name="card" id="card" size="20" value={this.state.card} onChange={this._onChange}/>
</div>
<p>You can even externally update the card state like a standard input element:</p>
<div className="form-field">
<label htmlFor="card">Externally Update:</label>
<input onChange={this._onChange} name="card" maxLength="16" style={{borderBottom: '1px solid #999'}} />
</div>
<p>Placeholders are automatically generated but can be overridden with your own:</p>
<div className="form-field">
<label htmlFor="expiry">Expiry Date:</label>
<MaskedInput mask="11/1111" name="expiry" id="expiry" placeholder="mm/yyyy" onChange={this._onChange}/>
</div>
<div className="form-field">
<label htmlFor="ccv">CCV:</label>
<MaskedInput mask="111" name="ccv" id="ccv" onChange={this._onChange}/>
</div>
<div className="form-field">
<label htmlFor="plate">License Plate:</label>
<MaskedInput mask="AAA 1111" name="plate" id="plate" onChange={this._onChange} placeholder="ABC 1234"/>
</div>
<p>Mask placeholder characters can be escaped with a leading <code>\</code> to use them as static contents:</p>
<div className="form-field">
<label htmlFor="escaped">Escaped:</label>
<MaskedInput mask="11 \* 11" name="escaped" id="escaped" onChange={this._onChange}/>
</div>
<p>Leading static characters:</p>
<div className="form-field">
<label htmlFor="leading">Leading:</label>
<MaskedInput mask="(0) 111 1111" name="leading" id="leading" onChange={this._onChange}/>
</div>
<p>Changing patterns:</p>
<div className="form-field">
<label htmlFor="changing">Input:</label>
<MaskedInput mask={this.state.pattern} name="changing" id="changing" onChange={this._onChange}/>
</div>
<div className="form-field">
<label htmlFor="pattern">Pattern:</label>
<select onChange={this._changePattern}>
{PATTERNS.map(pattern => <option value={pattern} key={pattern}>{pattern}</option>)}
</select>
</div>
<p>Dynamically changing the pattern as the user types:</p>
<div className="form-field">
<label htmlFor="changing">Credit Card:</label>
<MaskedInput mask={this.state.cardPattern} name="creditCard" id="creditCard" onChange={this._onCardChange}/>
</div>
<p>Custom format character (<code>W=[a-zA-Z0-9_]</code>, transformed to uppercase) and placeholder character (en space):</p>
<div className="form-field">
<label htmlFor="custom">Custom:</label>
<CustomInput name="custom" id="custom" onChange={this._onChange}/>
</div>
<hr/>
<pre><code>{JSON.stringify(this.state, null, 2)}</code></pre>
<hr/>
<footer><a href="https://github.com/insin/react-maskedinput">Source on GitHub</a></footer>
</div>
<p>You can even externally update the card state like a standard input element:</p>
<div className="form-field">
<label htmlFor="card">Externally Update:</label>
<input onChange={this._onChange} name="card" maxLength="16" style={{borderBottom: '1px solid #999'}} />
</div>
<p>Placeholders are automatically generated but can be overridden with your own:</p>
<div className="form-field">
<label htmlFor="expiry">Expiry Date:</label>
<MaskedInput mask="11/1111" name="expiry" id="expiry" placeholder="mm/yyyy" onChange={this._onChange}/>
</div>
<div className="form-field">
<label htmlFor="ccv">CCV:</label>
<MaskedInput mask="111" name="ccv" id="ccv" onChange={this._onChange}/>
</div>
<div className="form-field">
<label htmlFor="plate">License Plate:</label>
<MaskedInput mask="AAA 1111" name="plate" id="plate" onChange={this._onChange} placeholder="ABC 1234"/>
</div>
<p>Mask placeholder characters can be escaped with a leading <code>\</code> to use them as static contents:</p>
<div className="form-field">
<label htmlFor="escaped">Escaped:</label>
<MaskedInput mask="11 \* 11" name="escaped" id="escaped" onChange={this._onChange}/>
</div>
<p>Leading static characters:</p>
<div className="form-field">
<label htmlFor="leading">Leading:</label>
<MaskedInput mask="(0) 111 1111" name="leading" id="leading" onChange={this._onChange}/>
</div>
<p>Changing patterns:</p>
<div className="form-field">
<label htmlFor="changing">Input:</label>
<MaskedInput mask={this.state.pattern} name="changing" id="changing" onChange={this._onChange}/>
</div>
<div className="form-field">
<label htmlFor="pattern">Pattern:</label>
<select onChange={this._changePattern}>
{PATTERNS.map(pattern => <option value={pattern} key={pattern}>{pattern}</option>)}
</select>
</div>
<p>Dynamically changing the pattern as the user types:</p>
<div className="form-field">
<label htmlFor="changing">Credit Card:</label>
<MaskedInput mask={this.state.cardPattern} name="creditCard" id="creditCard" onChange={this._onCardChange}/>
</div>
<p>Custom format character (<code>W=[a-zA-Z0-9_]</code>, transformed to uppercase) and placeholder character (en space):</p>
<div className="form-field">
<label htmlFor="custom">Custom:</label>
<CustomInput name="custom" id="custom" onChange={this._onChange}/>
</div>
<hr/>
<pre><code>{JSON.stringify(this.state, null, 2)}</code></pre>
<hr/>
<footer><a href="https://github.com/insin/react-maskedinput">Source on GitHub</a></footer>
</div>
</React.StrictMode>)
}
}

Expand Down
54 changes: 23 additions & 31 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,48 +67,29 @@ class MaskedInput extends React.Component {
value: ''
}

componentWillMount() {
let options = {
pattern: this.props.mask,
value: this.props.value,
formatCharacters: this.props.formatCharacters
}
if (this.props.placeholderChar) {
options.placeholderChar = this.props.placeholderChar
}
this.mask = new InputMask(options)
}

componentWillReceiveProps(nextProps) {
if (this.props.mask !== nextProps.mask && this.props.value !== nextProps.mask) {
componentDidUpdate(prevProps) {
if (prevProps.mask !== this.props.mask && prevProps.value !== this.props.mask) {
// if we get a new value and a new mask at the same time
// check if the mask.value is still the initial value
// - if so use the nextProps value
// - if so use the this.props value
// - otherwise the `this.mask` has a value for us (most likely from paste action)
if (this.mask.getValue() === this.mask.emptyValue) {
this.mask.setPattern(nextProps.mask, {value: nextProps.value})
this.mask.setPattern(this.props.mask, {value: this.props.value})
}
else {
this.mask.setPattern(nextProps.mask, {value: this.mask.getRawValue()})
this.mask.setPattern(this.props.mask, {value: this.mask.getRawValue()})
}
}
else if (this.props.mask !== nextProps.mask) {
this.mask.setPattern(nextProps.mask, {value: this.mask.getRawValue()})
else if (this.props.mask !== this.props.mask) {
this.mask.setPattern(this.props.mask, {value: this.mask.getRawValue()})
}
else if (this.props.value !== nextProps.value) {
this.mask.setValue(nextProps.value)
else if (this.props.value !== this.props.value) {
this.mask.setValue(this.props.value)
}
}

componentWillUpdate(nextProps, nextState) {
if (nextProps.mask !== this.props.mask) {
this._updatePattern(nextProps)
}
}

componentDidUpdate(prevProps) {
if (prevProps.mask !== this.props.mask && this.mask.selection.start) {
this._updateInputSelection()
if (this.props.mask !== prevProps.mask) {
this.mask.selection.start && this._updateInputSelection()
this._updatePattern(this.props)
}
}

Expand Down Expand Up @@ -252,6 +233,17 @@ class MaskedInput extends React.Component {
}

render() {
let options = {
pattern: this.props.mask,
value: this.props.value,
formatCharacters: this.props.formatCharacters
}

if (this.props.placeholderChar) {
options.placeholderChar = this.props.placeholderChar
}

this.mask = new InputMask(options)
let ref = r => { this.input = r }
let maxLength = this.mask.pattern.length
let value = this._getDisplayValue()
Expand Down