React-提交时将所有空输入字段的setState设置为True

时间:2019-06-23 23:14:18

标签: javascript reactjs forms setstate

如果输入字段为空,我想将State动态设置为true。这样,当状态为true时,我可以通过css类为每个输入字段设置空样式。

在我当前的代码中,即使所有输入均为空,它也会循环运行并将最后一个空项目设置为true。在我看来,我认为应该将所有空值都设置为true,但是看起来循环只会识别上一次迭代。

对于所有空输入,如何将State设置为true?

HTML:

<form noValidate onSubmit={this.handleSubmit}>
  <label>Name</label>
  <input className="form-input" type="text" name="name">

  <label>Email</label>
  <input className="form-input" type="text" name="email">

  <label>Message</label>
  <input className="form-input" type="text" name="message">
</Form>

状态:

this.state = {
  errors: {
    name: false,
    email: false,
    message: false,
  },
};

JS:

handleSubmit = (e) => {

let inputFields = document.getElementsByClassName('form-input');

for (var i = 0; i < inputFields.length; i++) {
  if (inputFields[i].value === '') {

    let inputName = inputFields[i].name;

    this.setState({
      errors: {
        [inputName]: true,
      },
    });
  }
}

}

2 个答案:

答案 0 :(得分:1)

问题是setState仅将根密钥合并到状态中。 在您的情况下,您的状态为{ errors { ... } },通过执行setState({ error: { ... } }),react会替换状态内的整个错误对象。

您可以在循环中制作errors对象,并且只执行一次setState

handleSubmit = (e) => {
  let inputFields = document.getElementsByClassName('form-input');
  let errors = {};
  for (var i = 0; i < inputFields.length; i++) {
    if (inputFields[i].value === '') {
      let inputName = inputFields[i].name;
      errors[inputName] = true;
    }
  }
  this.setState({errors});
}

那是更好的方法。但是,如果您还研究这种方法,可能有助于了解setState的工作原理:

您可以将密钥从errors移到您的状态的根,因此react将它们合并到状态中,而不是替换它们。

this.state = {
 nameError: false,
 emailError: false,
 messageError: false,
};

this.setState({
  [`${inputName}Error`]: true,
});

答案 1 :(得分:0)

要在保持组件当前状态结构的同时实现所需的功能,请考虑对handleSubmit进行以下更改:

handleSubmit = (e) => {
    let inputFields = document.getElementsByClassName('form-input');

    /* Define errors object which will contain updated errors state based
    on form values */
    let errors = {};

    for (var i = 0; i < inputFields.length; i++) {
    if (inputFields[i].value === '') {

        let inputName = inputFields[i].name;

        /* Gather all error state into a single object */
        errors = { ...errors, [inputName]: true };
    }
    }

    /* Call setState once - this is more efficient and simplifies updating
    the nested errors object */
    this.setState((state) => {

        /* Replace nested error state with newly defined errors object */
        return { ...state, errors }
    });
}

在这里,我们利用errors状态相对于表单的行为,因为它可以根据handleSubmit函数期间表单输入的值来重新创建。

首先,根据表单输入的值在本地定义errors对象。这个errors对象根据输入值捕获表单的新错误状态。最后,setState通过回调被调用一次。在这里,本地创建的errors对象被指定为组件的新嵌套errors状态。