2015-10-20 58 views
0

我想在React中構建一個密碼確認表單,但是我無法獲得輸入驗證以雙向工作。重現:比較表單組件值

  • 輸入密碼。
  • 輸入一個匹配的確認密碼。
  • 編輯確認密碼,以便它不再匹配。
  • 編輯密碼字段以匹配確認密碼。

最後一步不起作用,我認爲我在handlePasswordInput中設置密碼狀態的方式有問題。在調用此方法時,isConfirmedPassword方法中的this.state.password方法不保留最新密碼。

我創建了一個二進制位代碼:https://jsbin.com/sufupedayi/edit?js,output

任何陣營的專家誰可以點我在正確的方向?

SignIn = React.createClass({ 
    getInitialState() { 
     return { 
      password: null, 
      confirmPassword: null 
     } 
    }, 
    handlePasswordInput(value) { 
     if (!_.isEmpty(this.state.confirmPassword)) { 
      this.refs.confirmPassword.validate(value); 
     } 

     this.setState({ 
      password: value 
     }) 
    }, 
    handleConfirmPasswordInput(value) { 
     this.setState({ 
      confirmPassword: value 
     }) 
    }, 
    isConfirmedPassword(value) { 
     return (value === this.state.password) 

    }, 
    render() { 
     return (
      <form autoComplete="off"> 
       <Input 
        name="password" 
        placeholder="Password" 
        errorMessage="Password is required" 
        onChange={this.handlePasswordInput} 
       /> 
       <Input 
        ref="confirmPassword" 
        name="confirmPassword" 
        placeholder="Confirm password" 
        errorMessage="Passwords do not match" 
        onChange={this.handleConfirmPasswordInput} 
        validate={this.isConfirmedPassword} 
       /> 
       <button type="submit">Submit</button> 
      </form> 
     ) 
    } 
}); 

Input = React.createClass({ 
    getInitialState() { 
     return { 
      valid: false, 
      value: null, 
      errorMessage: this.props.errorMessage, 
      errorVisible: false 
     } 
    }, 
    handleChange(event) { 
     this.setState({ 
      value: event.target.value 
     }) 

     if (this.props.validate) { 
      this.validate(event.target.value); 
     } 

     if (this.props.onChange) { 
      this.props.onChange(event.target.value); 
     } 

    }, 
    validate(value) { 
     if (this.props.validate && this.props.validate(value)) { 
      this.setState({ 
       valid: true, 
       errorVisible: false 
      }); 
     } else { 
      this.setState({ 
       valid: false, 
       errorVisible: true 
      }); 
     } 
    }, 
    render() { 
     return (
      <div> 
       <input 
        name={this.props.name} 
        placeholder={this.props.placeholder} 
        onChange={this.handleChange} 
       /> 
       {!this.state.valid && <InputError errorMessage={this.state.errorMessage} visible={this.state.errorVisible} />} 
      </div> 
     ) 
    } 
}); 

InputError = React.createClass({ 
    render() { 
     var divStyle = { 
      display: this.props.visible ? 'inline-block': 'none' 
     } 
     return (
      <div style={divStyle}>{this.props.errorMessage}</div> 
     ) 
    } 
}) 

React.render(<SignIn />, document.body); 

回答

1

用這個替換你的handlePasswordInput。它發生的原因是,你的handlePasswordInput被調用之前密碼已更新的狀態。這在您輸入確認密碼字段時不會發生,因爲密碼已在狀態中更新。

工作小提琴 - https://jsbin.com/cipuguxezi/1/edit?html,js,output

handlePasswordInput(value) { 
     this.setState({ 
     password: value 
     }); 
     var self= this; 
     window.setTimeout(function(){ 
     if (self.state.confirmPassword && self.state.confirmPassword.length) { 
     self.refs.confirmPassword.validate(self.state.confirmPassword); 
     } 
    }); 

} 

注:有在JSBIN一些bug,請確保

<div id="app"/> 

存在的腳本標籤上面。

+0

雖然這確實起作用,但它不覺得是一個合適的解決方案。 @多米尼克 - 托比亞斯的解決方案感覺更好。他的解決方案指出了我的正確方向。 – Stuiterbal

0

我覺得你讓這個比你需要的更加複雜,所以你已經遇到了競爭條件的麻煩,很難跟隨代碼。試試這個:

var SignIn = React.createClass({ 
    getInitialState() { 
     return { 
      password: null, 
      valid: false 
     } 
    }, 

    checkRequired(value) { 
     return !!value.trim(); 
    }, 

    checkPasswordsMatch(value) { 
     var match = this.refs.password.getValue() === value; 
     this.setState({ 
      valid: match, 
      password: value 
     }); 
     return match; 
    }, 

    render() { 
     return (
      <form autoComplete="off"> 
       <Input 
        ref="password" 
        name="password" 
        placeholder="Password" 
        errorMessage="Password is required" 
        validate={this.checkRequired} 
       /> 
       <Input 
        name="confirmPassword" 
        placeholder="Confirm password" 
        errorMessage="Passwords do not match" 
        validate={this.checkPasswordsMatch} 
       /> 
       <button type="submit">Submit</button> 
      </form> 
     ) 
    } 
}); 

var Input = React.createClass({ 
    getInitialState() { 
     return { 
      hasChanged: false, 
      valid: false 
     } 
    }, 
    handleChange(event) { 
     if (this.props.validate) { 
      this.setState({ 
       valid: this.props.validate(event.target.value) 
      }); 
     } 

     this.setState({ 
      hasChanged: true 
     }); 
    }, 

    getValue() { 
     //return this.refs.input.value; // For React 0.14+ 
     return this.refs.input.getDOMNode().value; 
    }, 

    render() { 
     return (
      <div> 
       <input 
        ref="input" 
        name={this.props.name} 
        placeholder={this.props.placeholder} 
        onChange={this.handleChange} 
       /> 
       {this.state.hasChanged && !this.state.valid && <InputError errorMessage={this.props.errorMessage} />} 
      </div> 
     ) 
    } 
}); 

var InputError = React.createClass({ 
    render() { 
     return (
      <div>{this.props.errorMessage}</div> 
     ) 
    } 
}) 

例如 https://jsbin.com/febagojayo/edit?js,output

+1

事實上,也許更好的方法,但不幸的是,這是行不通的。驗證不是兩種方式。匹配後編輯密碼字段不會顯示錯誤消息。 – Stuiterbal