简体   繁体   English

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

[英]React doesn't update component state when user changes input

I'm using React with express to render the views of my project server-side but I came across a problem. 我正在使用带有express的React来渲染项目服务器端的视图,但是遇到了一个问题。

I have a component where the users go after loging in for the first time. 我有一个组件,用户可以在首次登录后进入。 There are two inputs to write the user's new password and to confirm it. 有两个输入可以写入用户的新密码并进行确认。 I'm trying to validate that the password entered is 8 characters long at least and that the value of both inputs is the same. 我正在尝试验证输入的密码至少为8个字符长,并且两个输入的值都相同。

React doesn't seems to update the component state and thus, my verification process doesn't work. React似乎没有更新组件状态,因此,我的验证过程不起作用。 Am I doing something wrong? 难道我做错了什么? Here's the code: 这是代码:

set-password.jsx 设置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>
    )
  }

});

I'm using checkLength() on the first input to verify the password length. 我在第一个输入上使用checkLength()来验证密码长度。 Then checkPassword() verifies that both inputs have the same code and then update this.state.sPassword to be the first input value, which will be sent to the system endpoint. 然后, checkPassword()验证两个输入是否具有相同的代码,然后将this.state.sPassword更新为第一个输入值,该值将被发送到系统端点。

After the SubmitButton component I'm printing the value of this.state.sPassword to see if the state is changing, but it does not. SubmitButton组件之后,我将打印this.state.sPassword的值以查看状态是否正在更改,但状态没有更改。 Can you help me? 你能帮助我吗? Thanks. 谢谢。

Your issue is that you are not setting the value of sPassword properly from its own input, the only thing you are doing is setting it when the other input changes. 您的问题是您没有从自己的输入正确设置sPassword的值,唯一要做的就是在其他输入更改时对其进行设置。 Additionally, that code: 此外,该代码:

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

is redundant because you are setting sPassword to the same value it already has, assuming the true case passes. 这是多余的,因为您将sPassword设置为已经具有的相同值(假设通过了true大小写)。 Basically you are saying if '123' == password then set password to '123' . 基本上,您说的if '123' == password then set password to '123' Furthermore, that case will never happen because sPassword never gets updated from its own input and thus is always an empty string. 此外,这种情况将永远不会发生,因为sPassword永远不会从其自身的输入进行更新,因此始终是一个空字符串。

What you need to do is, instead of calling checkLength() in first inputs onChange , you call something like updateSPassword() to properly set the password. 你需要做的是什么,而不是调用checkLength()在第一次输入onChange ,你叫像updateSPassword()正确设置密码。 Further more you can do the same for the second input. 此外,您可以对第二个输入执行相同的操作。 Finally you can add a validate method that is called when either of the passwords change and that performs your validation: 最后,您可以添加一个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}
    />
  }

});

Or you can even combine the setting of passwords and validation into a single method: 或者,您甚至可以将密码设置和验证结合到一个方法中:

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
  });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM