Реагировать полученное состояние в форме с крючками - PullRequest
0 голосов
/ 13 апреля 2020

Я работал над формой регистрации для моего приложения 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",
      };
  }
}

Заранее спасибо за помощь!

1 Ответ

0 голосов
/ 13 апреля 2020

Возможно, это не точное решение, которое вы ищете, но именно так я обрабатываю проверку в своем коде.

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>
...