user3454914 user3454914 - 4 months ago 19
Javascript Question

React login page

I am trying to write login page in react but asynchronous nature of setState makes this rather difficult.

After submit printing out state gives old values set as initial state instead of updating state with form values.

I know that setState is asynchronous and that there is no guarantee that state will get updated, so what are my options here? How can I make sure that submit will get new values?

Is there possibly a better approach than this?

Code below.

var Login = React.createClass({
getInitialState: function() {
return {
name: '',
password: ''
}
},

handleSubmit: function(e) {
e.preventDefault();

var msg = {
name: this.state.name,
password: this.state.password
}

// name and password are not updated
console.log(msg)
},

handleChange: function(value, e) {
this.setState({ value: e.target.value })
},

render: function() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<Form horizontal>
<FormGroup controlId="formHorizontalName">
<Col componentClass={ControlLabel} sm={1}>
Name
</Col>
<Col sm={3}>
<FormControl type="text" placeholder="Name" value={this.state.name} onChange={this.handleChange.bind(this, 'name')}/>
</Col>
</FormGroup>

<FormGroup controlId="formHorizontalPassword">
<Col componentClass={ControlLabel} sm={1}>
Password
</Col>
<Col sm={3}>
<FormControl type="password" placeholder="Password" value={this.state.password} onChange={this.handleChange.bind(this, 'password')}/>
</Col>
</FormGroup>

<FormGroup>
<Col smOffset={1} sm={3}>
<Checkbox>Remember me</Checkbox>
</Col>
</FormGroup>

<FormGroup>
<Col smOffset={1} sm={3}>
<Button type="submit">
Sign in
</Button>
</Col>
</FormGroup>
</Form>
</form>
</div>
);
}
});

module.exports = Login;

Answer

Try by replacing your handleChange function by:

handleChange: function(value, e) {
    this.setState({ [value]: e.target.value })
},

Note that I add [ ] to specify I want update the value of the value variable (name or password) instead of the string value (your code)

Example:

   var value = "red" 
   var obj1 = {value: "foo"} // {value: "foo"}
   var obj2 = {color: value} // {color: "red"} 
   var obj3 = {[value]: "foo"} // {red: "foo"}