Reputation: 4154
Part of my code which fails looks like:
const normalizeInput = (value, previousValue) => {
if (!value) return value;
const currentValue = value.replace(/[^\d]/g, '');
const cvLength = currentValue.length;
if (!previousValue || value.length > previousValue.length) {
if (cvLength < 4) return currentValue;
if (cvLength < 7) return `(${currentValue.slice(0, 3)}) ${currentValue.slice(3)}`;
return `(${currentValue.slice(0, 3)}) ${currentValue.slice(3, 6)}-${currentValue.slice(6, 10)}`;
}
else {
if (cvLength < 4) return currentValue;
if (cvLength < 7) return `(${currentValue.slice(0, 3)}) ${currentValue.slice(3)}`;
}
};
class Example extends Component {
constructor(props) {
super(props);
console.log(JSON.stringify(props))
this.state = {
editable: {},
phoneNumber: '(123) 555-1234'
}
}
handlePhoneChange(id, value) {
this.setState(prevState=> ({ [id]: normalizeInput(value, prevState[id]) }));
};
render(){
return(
<input
type="text"
className="form-control react-form-input"
id="phoneNumber"
name="phoneNumber"
value={this.state.phoneNumber}
onChange={(e) => {this.handlePhoneChange('phoneNumber', e.target.value)}}
/>
)}
}
It will complain as
A component is changing a controlled input of type text to be uncontrolled. Input elements should not switch from controlled to uncontrolled
on value={this.state.phoneNumber}
but when I will set it as value={this.state.phoneNumber || ''}
will not but then on change will remove whole phoneNumber
value instead on character.
Any tips on that?
Upvotes: 0
Views: 44
Reputation: 196197
This happens because your normalizeInput
does not return anything when value.length <= previousValue.length
(when you delete something)
So the undefined
gets stored in your state and later given as value
to your input
, in effect making it uncontrolled.
The || ''
fixes that because when your value is undefined
you pass the ''
empty string and so the input
never receives an undefined
value.
Upvotes: 1