反应挂钩setState不会立即更新

时间:2019-06-08 21:17:51

标签: javascript reactjs

当我单击提交按钮时,我正在尝试验证字段。这就是我定义状态的方式。

  const [values, setValues] = useState({
    email: "",
    password: "",
    emailErrorMessage: "",
    passwordErrorMessage: "",
    errorMessage: "",
    emailError: false,
    passwordError: false,
    rememberMe: false,
  });

在Submit方法中,这就是我对其进行验证的方式。

if (values.email.length <= 0) {

  setValues({
    ...values,
    emailError: true,
    emailErrorMessage: "Email field must not be empty"
  })
};

if (values.password.length <= 0) {
  setValues({ ...values, passwordError: true, passwordErrorMessage: "Password field must not be empty" });
}

出于某种原因,它仅向我显示密码字段错误。尽管它同时经历了两个if条件。不知道我怎么能解决它。

预期:-它应该同时显示电子邮件和密码错误。

2 个答案:

答案 0 :(得分:3)

问题1:状态更新是一个异步过程,因此,在您的情况下,您是通过传播当前状态来第一次更新状态,然后针对第二次,通过传播当前状态(尚未更新)。结果,最后一次成功更新的状态(实际上是一场赌博,第二次更新的运气更大)将是实际的nextState,这就是为什么您遇到仅更新密码的原因

问题2::每个状态更新都会触发重新渲染。您将状态更新两次(即使它做错了,但这是事实),而您只能执行一次(只需重新渲染一次)。

解决这两个问题的解决方案是:

const newValues = {...values};
if (values.email.length <= 0) {
  newValues.emailError: true;
  newValues.emailErrorMessage: "Email field must not be empty";
};

if (values.password.length <= 0) {
  newValues.passwordError: true;
  newValues.passwordErrorMessage: "Password field must not be empty";
}
setValues(newValues);

答案 1 :(得分:-1)

@RaduNemerenco的回答很好,但是您可以添加另一个if语句来检查这两种情况

if (values.email.length <= 0) {

  setValues({
    ...values,
    emailError: true,
    emailErrorMessage: "Email field must not be empty"
  })
};

if (values.password.length <= 0) {
  setValues({ ...values, passwordError: true, passwordErrorMessage: "Password field must not be empty" });
}

if (values.email.length <= 0 && values.password.length <= 0) {

  setValues({
    ...values,
    emailError: true,
    emailErrorMessage: "Email field must not be empty",
    passwordError: true,
    passwordErrorMessage: "Password field must not be empty"
  })
};