当用户更改输入时,React不会更新组件状态

时间:2016-05-26 00:09:00

标签: javascript express input reactjs jsx

我使用React with express来渲染我的项目服务器端的视图,但我遇到了一个问题。

我有一个用户第一次登录后用户去的组件。有两个输入来写入用户的新密码并进行确认。我试图验证输入的密码至少是8个字符,并且两个输入的值都是相同的。

React似乎没有更新组件状态,因此我的验证过程不起作用。难道我做错了什么?这是代码:

设置password.jsx

module.exports = React.createClass({

  getInitialState: function() {
    return { 
      sPassword: '',
      validLength: false,
      validPassword: false
    }
  },

  checkLength: function(event) {
    var pLength = event.target.value;
    pLength.length >= 8 ? 
      this.setState({ validLength: true }) : 
      this.setState({ validLength: false });
  },

  checkPassword: function(event) {
    event.target.value === this.state.sPassword ? 
      this.setState({ validPassword: true, sPassword: event.target.value}) :
      this.setState({ validPassword: false });
  },

  render: function() {
    return (
      <Layout>
        <Form action='/auth/setpassword' method='POST' name='setPassword'>
          <h1>Welcome</h1>
          <p>...</p>
          <div className='row'>
            <div className='col-sm-6'>
              <Input 
                type='password' 
                label='Introduzca su nueva contraseña' 
                name='password' 
                onChange={this.checkLength}
                value={this.state.sPassword}
              />
            </div>
            <div className='col-sm-6'>
              <Input 
                type='password' 
                label='Escriba de nuevo su contraseña' 
                name='confirm_password'
                onChange={this.checkPassword}
              />
            </div>
          </div>
          <SubmitButton value='Guardar nueva contraseña' />
            <div>
              <p>Contraseña verificada: <span>{this.state.sPassword}</span></p>
            </div>
        </Form>
      </Layout>
    )
  }

});

我在第一个输入上使用checkLength()来验证密码长度。然后checkPassword()验证两个输入是否具有相同的代码,然后将this.state.sPassword更新为第一个输入值,该值将发送到系统端点。

SubmitButton组件之后,我打印this.state.sPassword的值以查看状态是否正在发生变化,但事实并非如此。你能帮助我吗?感谢。

1 个答案:

答案 0 :(得分:2)

您的问题是您没有从其自己的输入中正确设置sPassword的值,您唯一要做的就是在其他输入发生更改时进行设置。此外,该代码:

checkPassword: function(event) {
  event.target.value === this.state.sPassword ? 
    this.setState({ validPassword: true, sPassword: event.target.value}) :
    this.setState({ validPassword: false });
},

是多余的,因为您将sPassword设置为它已有的相同值,假设true情况通过。基本上你是在说if '123' == password then set password to '123'。此外,这种情况永远不会发生,因为sPassword永远不会从自己的输入中更新,因此总是一个空字符串。

您需要做的是,而不是在第一个输入checkLength()中调用onChange,而是调用类似updateSPassword()的内容来正确设置密码。您还可以为第二个输入执行相同的操作。最后,您可以添加一个validate方法,当其中一个密码更改并执行验证时调用该方法:

module.exports = React.createClass({

  getInitialState: function() {
    return { 
      sPassword: '',
      cPassword: '',
      validLength: false,
      validPassword: false
    }
  },

  setSPasswordAndValidate: function(e) {
    this.setState({
      sPassword: e.target.value
    });
    this.validate();
  },

  setCPasswordAndValidate: function(e) {
    this.setState({
      cPassword: e.target.value
    });
    this.validate();
  },

  validate: function() {
    var pw1 = this.state.sPassword;
    var pw2 = this.state.cPassword;

    var validPassword = pw1 === pw2;
    var validLength = validPassword && pw1.length >= 8;

    this.setState({
      validPassword: validPassword,
      validLength: validLength
    });
  }

  render: function() {

    // ...

    <Input 
      type='password' 
      label='Introduzca su nueva contraseña' 
      name='password' 
      onChange={this.setSPasswordAndValidate}
      value={this.state.sPassword}
    />
    // ...
    <Input 
      type='password' 
      label='Escriba de nuevo su contraseña' 
      name='confirm_password'
      onChange={this.setCPasswordAndValidate}
      value={this.state.cPassword}
    />
  }

});

或者您甚至可以将密码和验证的设置组合到一个方法中:

setSPasswordAndValidate: function(e) {
  this.validate(e.target.value, this.state.cPassword);
},

setCPasswordAndValidate: function(e) {
  this.validate(this.state.sPassword, e.target.value);
},

validate: function(sPassword, cPassword) {

  var validPassword = sPassword === cPassword;
  var validLength = validPassword && sPassword.length >= 8;

  this.setState({
    sPassword: sPassword,
    cPassword: cPassword,
    validPassword: validPassword,
    validLength: validLength
  });
}