如何使用useState和表单正确更新状态?

时间:2019-04-14 17:35:10

标签: javascript reactjs

我想编写一个简单的登录表单并验证输入。为此,我只有一个用户名和密码输入,以及一个提交输入的按钮。但是,错误状态只有在两次提交表单后才能正确更新。

const LoginForm = () => {
  const [account, setAccount] = useState({ username: "", password: "" });
  const [errors, setErrors] = useState({});

  const validate = () => {
    const newErrors = {};
    if (account.username.trim() === "")
      newErrors.username = "Username is required.";
    if (account.password.trim() === "")
      newErrors.password = "Password is required.";
    return Object.entries(newErrors).length === 0 ? null : newErrors;
  };

  const handleSubmit = e => {
    e.preventDefault();
    setErrors(validate());
    if (errors) return;
    // Call server
    console.log("Submitted");
  };

  const handleChange = ({ currentTarget: input }) => {
    account[input.name] = input.value;
    setAccount({ ...account });
  };

  return (
    <div>
      <h1>Login</h1>
      <form onSubmit={handleSubmit}>
        <Input
          name="username"
          value={account.username}
          label="Username"
          onChange={handleChange}
        />
        <Input
          name="password"
          value={account.password}
          label="Password"
          onChange={handleChange}
        />
        <button className="btn btn-primary">Login</button>
      </form>
    </div>
  );
};
如果两个输入字段都不为空,则应将

error设置为null,否则应将其设置为包含错误描述的对象。

1 个答案:

答案 0 :(得分:1)

在您首次提交时,您仍在引用旧的错误状态,因此您的代码将无法工作。下一次渲染后,errors变量将更新。您需要像这样更改句柄提交。

const handleSubmit = e => {
    e.preventDefault();
    const updatedErrors = validate();
    // setErrors won't change the value of errors at this point but when the re-render
    // happens the new errors variable will have your updates
    setErrors(updatedErrors);
    if (updatedErrors) return;
    // Call server
    console.log("Submitted");
  };

考虑使用旧的setState。如果您具有以下条件:

const { errors } = this.state;
const updatedErrors = validate();
this.setState(updatedErrors);
// at this point errors !== newErrors