2016-07-23 259 views
2

我正在嘗試編寫登錄頁面,但setState的異步性質使這非常困難。React登錄頁面

提交打印出狀態後,將舊值設置爲初始狀態,而不是使用表單值更新狀態。

我知道setState是異步的,並且不能保證狀態會得到更新,所以我的選擇是什麼?我怎樣才能確保提交將獲得新的價值?

有沒有比這更好的方法?

下面的代碼。

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; 
+0

你可以添加一個'的console.log({值:e.target.value})上'handleChange' – Arthur

+0

'如果在FormControls名稱,密碼值字段它打印出來只有最後一個字母,否則它會打印到目前爲止寫入的整個字符串。相當令人費解。 – user3454914

回答

1

嘗試通過更換您的handleChange功能:

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

注意,我添加[]指定我想更新value變量(namepassword)的值,而不是字符串value(您的代碼)

示例

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

嗯,那工作。你能解釋爲什麼嗎? – user3454914

+1

@ user3454914這與異步setState無關(這很快發生,除非您依賴於同一個堆棧中的新狀態,否則它永遠不會成爲問題)。你正在設置「值」狀態,所以你可以用'this.state.value'來訪問它。你的handleChange函數根本不會影響名字'name'和'password'道具。 –

+0

更新以解釋 – Arthur