【问题标题】:React derived state in form with hooks使用钩子以形式反应派生状态
【发布时间】:2020-04-13 13:51:22
【问题描述】:

我一直在为我的 React 应用程序(使用 Next.js)制作一个注册表单,并且我真的在为表单验证而苦苦挣扎。我见过的许多示例注册页面,隐藏invalid 消息,直到用户与输入交互。我尝试通过在输入字段为空时隐藏invalid 消息来重新创建它,但是当用户键入内容然后将其删除时它不会显示任何内容。我想在用户尚未输入任何内容时隐藏invalid 消息,然后在表单有效之前显示它。我如何在 React 中做到这一点?我的页面:

const SignUp: NextPage = () => {
  const firebase = useFirebase();
  const router = useRouter();

  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [emailValid, setEmailValid] = useState({
    valid: true,
    message: "",
  });
  const [
    passwordValid,
    setPasswordValid,
  ] = useState({
    valid: true,
    message: "",
  });

  useEffect(() => {
    if (email === "") {
      setEmailValid({
        valid: true,
        message: "",
      });
      return;
    }
    const { valid, message } = validateInput(
      "email",
      email
    );

    setEmailValid({
      valid,
      message,
    });
  }, [email]);

  useEffect(() => {
    if (password === "") {
      setPasswordValid({
        valid: true,
        message: "",
      });
      return;
    }

    const { valid, message } = validateInput(
      "password",
      password
    );

    setPasswordValid({
      valid,
      message,
    });
  }, [password]);

  const handleSubmit = useCallback(
    (event: FormEvent<HTMLFormElement>) => {
      event.preventDefault();
      if (
        emailValid.valid === true &&
        passwordValid.valid === true &&
        email !== "" &&
        password !== ""
      ) {
        const error = firebase.createUser(
          email,
          password
        );
        if (error) {
          console.warn(error.code);
        } else {
          router.push("/");
        }
      } else {
        console.warn("Invalid user values");
      }
    },
    [
      email,
      emailValid.valid,
      firebase,
      password,
      passwordValid.valid,
      router,
    ]
  );

  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="email">Email</label>
      <input
        value={email}
        onChange={(event): void =>
          setEmail(event.target.value)
        }
        id="email"
        placeholder="Email"
      />
      <p>{emailValid.message}</p>
      <label htmlFor="password">Password</label>
      <input
        value={password}
        onChange={(event): void =>
          setPassword(event.target.value)
        }
        id="password"
        placeholder="Password"
      />
      <p>{passwordValid.message}</p>
      <button type="submit">Submit</button>
    </form>
  );
};

export default SignUp;

我的验证函数如下所示:

type InputType = "email" | "password";

function validateInput(
  inputType: InputType,
  inputValue: string
): { valid: boolean; message: string } {
  switch (inputType) {
    case "email":
      if (!inputValue.includes("@")) {
        return {
          valid: false,
          message:
            "The email field must be a valid email",
        };
      } else {
        return {
          valid: true,
          message: "",
        };
      }

    case "password":
      if (inputValue.length < 8) {
        return {
          valid: false,
          message:
            "The password field must be at least 8 characters",
        };
      } else if (
        inputValue.toUpperCase() === inputValue
      ) {
        return {
          valid: false,
          message:
            "The password must contain an lowercase character",
        };
      } else if (
        inputValue.toLocaleLowerCase() ===
        inputValue
      ) {
        return {
          valid: false,
          message:
            "The password must contain an uppercase character",
        };
      } else if (
        /\d/.test(inputValue) === false
      ) {
        return {
          valid: false,
          message:
            "The password must contain a number",
        };
      } else {
        return {
          valid: true,
          message: "",
        };
      }

    default:
      return {
        valid: false,
        message: "Input type is invalid",
      };
  }
}

提前感谢您帮助我!

【问题讨论】:

    标签: reactjs typescript forms validation next.js


    【解决方案1】:

    这可能不是您正在寻找的确切解决方案,但这就是我在代码中处理验证的方式。

    const [name, setName] = React.useState("")
    const [error, setError] = React.useState(false)
    
    const handleClick = () => {
    /// Your error conditions here. Match them with if or switch.
    /// If form is invalid, setError to true.
    setError(true)
    }
    
    <form>
    <input type="text" value={name} onChange={e => setName(e.target.value)} />
    {error && name.length<1 ? <span>Name is required</span>}
    <button onClick={handleClick}>Click</button>
    </form>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-22
      • 2022-11-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-12
      • 2020-10-23
      相关资源
      最近更新 更多