如何在 React Form 中确认密码?

问题描述 投票:0回答:1

我在 styled-component 中使用 ReactBootstrap ,在 Context 中存储 formData

我希望 Form.Control 保持其原始样式,并仅在我第一次输入后才开始检查验证。

当我更改名称和帐户时,反馈div可以正常工作,

但是当我 onChange password 和 informPassword 时,它们的反馈 div 渲染不会随 onChange 事件更新。

上下文正确,但渲染不正确, 我知道 setState 意味着在下一个渲染中更新,但我的 informCheck 也是一个状态?
我该如何解决这个问题

FormContainer.jsx

import { useState } from "react";
import Form from "react-bootstrap/Form";

function FormContainer({ children, handleSubmitExtend }) {
  const [validated, setValidated] = useState(false);

  const handleSubmit = (event) => {
    const form = event.currentTarget;
    console.log("組件", form);
    event.preventDefault();
    event.stopPropagation();
    setValidated(true);
    handleSubmitExtend();
  };

  return (
    <Form noValidate validated={validated} onSubmit={handleSubmit}>
      {children}
    </Form>
  );
}

export default FormContainer;

表单输入.jsx

import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";
import Form from "react-bootstrap/Form";
import { useEffect, useState } from "react";

export default function FormInput({
  label,
  type,
  value,
  placeholder,
  onChange,
  invalidPrompt,
  minlength,
  maxlength,
  confirmCheck = true,
}) {
  const handleFormChange = (e) => {
    const inputNode = e.target;
    if (inputNode.validity.valid && confirmCheck) {
      inputNode.classList.remove("is-invalid");
      inputNode.classList.add("is-valid");
    } else {
      inputNode.classList.add("is-invalid");
      inputNode.classList.remove("is-valid");
    }
  };
  return (
    <Row>
      <Form.Group as={Col} md="12">
        <Form.Label htmlFor={label}>{label}</Form.Label>
        <Form.Control
          className="mb-3 input-rows"
          id={label}
          required
          type={type}
          placeholder={placeholder}
          defaultValue={value}
          value={value}
          onChange={(e) => {
            onChange?.(e.target.value);
            handleFormChange(e);
          }}
          minLength={minlength}
          maxLength={maxlength}
        />
        <Form.Control.Feedback>OK!</Form.Control.Feedback>
        <Form.Control.Feedback type="invalid">
          {invalidPrompt}
        </Form.Control.Feedback>
      </Form.Group>
    </Row>
  );
}

注册页面.jsx

import styled from "styled-components";
import { useEffect, useState } from "react";

import { useAuth } from "../context/AuthContext";
import Swal from "sweetalert2";
import FormContainer from "../components/AuthForm/FormContainer";
import FormInput from "../components/AuthForm/FormInput";

export default function RegisterPageTest() {
  const defaultForm = {
    account: "",
    password: "",
    confirmPassword: "",
    name: "",
  };
  const [form, setForm] = useState(defaultForm);
  const [confirmCheck, setConfirmCheck] = useState(true);
  const handleInputOnchange = (attr, inputValue) => {
    setForm({
      ...form,
      [attr]: inputValue,
    });
    setConfirmCheck(form.password === form.confirmPassword);
  };
  const { login, isLogin } = useAuth();
  const handleSubmit = async () => {
    const { name, account, password, confirmPassword } = form;
    console.log(name, account);
    if (
      name.length < 2 ||
      account.length < 4 ||
      password.length < 4 ||
      confirmPassword.length < 4
    ) {
      Swal.fire({
        title: "error",
        text: "Error",
        icon: "question",
      });
      return;
    }
    try {
      const status = await login(form);
      if (status === "success") {
        Swal.fire({
          title: "success!",
          text: "success",
          icon: "success",
        });
      } else {
        Swal.fire({
          title: "註冊失敗!",
          button: "好",
          icon: "success",
        });
      }
    } catch (error) {
      console.log(error);
    }
  };

  return (
    <AuthPage>
      <AuthContainer>
        <FormContainer handleSubmitExtend={handleSubmit}>
          <AuthTitle>Sign up for free </AuthTitle>
          <FormInput
            key={form}
            label="account"
            type="text"
            placeholder="account"
            value={form.account}
            onChange={(inputValue) =>
              handleInputOnchange("account", inputValue)
            }
            invalidPrompt={"At least 4 or more characters"}
            minlength={4}
            maxlength={16}
          ></FormInput>
          <FormInput
            key={form}
            label="password"
            type="password"
            placeholder="password..."
            value={form.password}
            onChange={(inputValue) =>
              handleInputOnchange("password", inputValue)
            }
            invalidPrompt={"At least 4 or more characters"}
            minlength={4}
            maxlength={16}
            confirmCheck={confirmCheck}
          ></FormInput>
          <FormInput
            key={form}
            label="confirmPassword"
            type="password"
            placeholder="confirmPassword"
            value={form.confirmPassword}
            onChange={(inputValue) =>
              handleInputOnchange("confirmPassword", inputValue)
            }
            invalidPrompt={
              form.confirmPassword !== form.password
                ? "password doesn't match"
                : "At least 4 or more characters"
            }
            confirmCheck={confirmCheck}
            minlength={4}
            maxlength={16}
          ></FormInput>
          <FormInput
            key={form}
            label="用戶名稱"
            type="text"
            placeholder="username..."
            value={form.name}
            onChange={(inputValue) => handleInputOnchange("name", inputValue)}
            invalidPrompt={"At least 1 or more characters"}
            minlength={1}
            maxlength={16}
          ></FormInput>
          <AuthButton>註冊</AuthButton>
          <AuthLink>
            已經有帳號了? <a href="/login">登入</a>
          </AuthLink>
        </FormContainer>
      </AuthContainer>

      <AuthBanner>大圖片</AuthBanner>
    </AuthPage>
  );
}

const AuthPage = styled.div`
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: row;
`;

const AuthContainer = styled.div`
  background-color: ${({ theme }) => theme.containerBackground};
  display: flex;
  flex-wrap: wrap;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 50%;
  margin-top: 120px;
`;

const AuthBanner = styled.div`
  display: flex;
  width: 50%;
  flex-wrap: wrap;
  flex-direction: column;
  justify-content: center;
  align-items: center;
`;

const AuthButton = styled.button`
  border-radius: 5px;
  background-color: #217c4a;
  border: none;
  cursor: pointer;
  color: white;
  min-width: 300px;
  font-family: "Noto Sans TC", sans-serif;
  font-weight: bold;
  padding: 6px 0;
  margin: 2rem 0;
  &.hover {
    cursor: pointer;
  }
`;

const AuthTitle = styled.div`
  width: 100%;
  text-align: center;
  font-size: 24px;
  font-weight: bold;
  text-align: start;
`;
const AuthLink = styled.div`
  width: 100%;
  display: flex;
  justify-content: center;
  text-align: center;
`;

我尝试过useEffect,但它也不起作用,我尝试了4个多小时......

reactjs styled-components form-control
1个回答
0
投票

我不知道这是否是一个好方法。

我使用 DOM 作为当前值并更新 DOM

const checkConfirm = () => {
    const password = document.querySelector("#password");
    const confirmPassword = document.querySelector("#confirmPassword");
    console.log(password.value ,confirmPassword.value)
    if (password.value === confirmPassword.value) {
      password.classList.remove("is-invalid");
      password.classList.add("is-valid");
      confirmPassword.classList.remove("is-invalid");
      confirmPassword.classList.add("is-valid");
    } else {
      password.classList.add("is-invalid");
      password.classList.remove("is-valid");
      confirmPassword.classList.add("is-invalid");
      confirmPassword.classList.remove("is-valid");
    }
  };

© www.soinside.com 2019 - 2024. All rights reserved.