Touch Touch - 4 years ago 73
Javascript Question

Keep getting a controlled vs uncontrolled react error

I keep getting this error in my console:


warning.js?8a56:36 Warning: LoginForm is changing a controlled input
of type password to be uncontrolled. Input elements should not switch
from controlled to uncontrolled (or vice versa). Decide between using
a controlled or uncontrolled input element for the lifetime of the
component. More info: https://facebook.github.io/react/docs/forms.html#controlled-components


I have had a look at these questions:



Here is the component:

export default class LoginForm extends Component {
constructor(props) {
super(props);
this.state = {
values: {
username: "",
password: ""
}
};

this.onChange = this.onChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this._clearInput = this._clearInput.bind(this);
}

onSubmit(event) {
// this.props.attemptLogin
event.preventDefault();
console.log(this.state.values);
let {username, password} = this.state.values;

this.props.attemptLogin(username, password)
.then((userInfo) => {
console.log(userInfo);
LocalStore.setJson('api', userInfo.api);
LocalStore.setJson('user', userInfo.user);

this._clearInput('username' , 'password');

})
.catch((err) => {
console.log("Failed:");
console.log(err);
this._clearInput('password');
});
}

_clearInput(...fields) {
let newValuesState = {};
fields.forEach((field) => {
newValuesState[field] = '';
});
this.setState({values: newValuesState});
}

onChange(event) {
let name = event.target.name;
let value = event.target.value;
this.setState({values: {[name]: value}});
}

render() {
return (
<div>
<form method="post" onSubmit={this.onSubmit}>
<div><input type="text" name="username" onChange={this.onChange} value={this.state.values.username}/></div>
<div><input type="password" name="password" onChange={this.onChange} value={this.state.values.password}/></div>
<div><button type="submit">Login</button></div>
</form>
</div>
);
}
}

LoginForm.propTypes = {
attemptLogin: React.PropTypes.func.isRequired
};


The code does seem to work but this error pops up in the console and so I can't continue I till I get it to stop appearing. Can anyone see what's I did wrong in the component?

Answer Source

Since you are nesting the values in state.values, your onChange function will remove the field not being changed. You could do something like this instead:

onChange(event) {
    let name = event.target.name;
    let value = event.target.value;
    let values = {...this.state.values};
    values[name] = value;
    this.setState({values}});
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download