0

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?

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

OK, but what causing to delete whole input value when I will add || ' and then I will delete something? Should be better to have added else statement in normalizeInput to return edited value?
I have added else statement to the normalizeInput and it still complains about switching element to uncontrolled.
@JackTheKnife if cvLength >= 7 in your else block, you still return undefined. There should be no way your normalizeInput to return undefined or the input will become uncontrolled.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.