簡體   English   中英

react-hook useFormInput() 表單驗證不起作用

[英]react-hook useFormInput() form validation not working

代碼沙箱鏈接https://stackblitz.com/edit/react-cdv6mx?devtoolsheight=33&file=src/ResetPassword.js

解釋:當用戶輸入不正確的詳細信息時,服務器會發送 400: bad request error 和一條消息,該消息可以在網絡選項Response tab下的Response tab看到。 目的是在提交表單之前驗證表單域,並在輸入不正確的域時顯示錯誤消息。 此外,目的是禁用重置按鈕,直到表單字段符合條件。 因此,這將防止用戶意外提交輸入一半的字段。

我有一個功能組件,其中有一個簡單的表單。

問題:我在onChange上調用validatForm()方法。 該方法應首先檢查 newPassword 和 confirmPassword 是否相同並符合密碼規則(要求),如果為真,則發送數據。

更新的代碼位於上面的 STACKBLITZ 鏈接中。

我使用useFormInput()如下

  const email = useFormInput("");
  const newPassword = useFormInput("");
  const confirmPassword = useFormInput("");

我寫了一個useFormInput()方法

const useFormInput = (initialValue) => {
  const [value, setValue] = useState(initialValue);

  const handleChange = (e) => {
    setValue(e.target.value);
  };
  return {
    value,
    onChange: handleChange,
  };
};

和一個validateForm()方法,我將它傳遞給我的<button/>

/*  Your password must contain at least one capital letter, one
      *number and one lowercase letter, and it must contain at least 8
      *characters*/


const validateForm = (event) => {
    let pass = event.target.value;
    let reg = /^(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).{8,}$/;
    let test = reg.test(pass);
    if (test) {
      this.setState({ value: event.target.value });
    } else {
      alert("password validation unsuccessful. Please try again.");
      return;
    }
  };

並在渲染()

<FormGroup row>
            <Label for="Email" sm={2}>
              Email
            </Label>
            <Col sm={4}>
              <Input
                type="email"
                name="email"
                id="Email"
                
                {...email}
              />
            </Col>
          </FormGroup>
          <FormGroup row>
            <Label for="newPassword" sm={2}>
              New Password
            </Label>
            <Col sm={4}>
              <Input
                type="password"
                name="password"
                id="newPassword"
                
                {...newPassword}
              />
            </Col>
          </FormGroup>
          <FormGroup row>
            <Label for="confirmPassword" sm={2}>
              Confirm Password
            </Label>
            <Col sm={4}>
              <Input
                type="password"
                name="confirmPassword"
                id="confirmPassword"
                
                {...confirmPassword}
              />
            </Col>
          </FormGroup>
          <div className="form-actions">
            {error && (
              <>
                <small style={{ color: "red" }}>{error}</small>
                <br />
              </>
            )}
            <br />

            <Col lg={{ offset: 2 }} sm={{ size: 1 }}>
              <Button
                className="mail-reset-btn"
                block
                type="submit"
                value={loading ? "Loading..." : "Login"}
                onClick={handleReset}
                disabled={!validateForm}
              >
                Reset
              </Button>
            </Col>
          </div>
        </Form>

更新您的validateForm以從表單onSubmit事件中解構密碼字段。 創建一個errors對象來跟蹤存在哪些字段錯誤。 如果errors對象為空,則驗證通過,否則設置錯誤狀態。

const validateForm = event => {
  event.preventDefault();

  const { confirmPassword, newPassword } = event.target;
  const errors = {};

  const regex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).{8,}$/;

  if (!regex.test(newPassword.value)) {
    errors.requirementUnmet = "New password does not meet requirements.";
  }

  if (newPassword.value !== confirmPassword.value) {
    errors.passwordMismatch = "Entered passwords do not match.";
  }

  if (!Object.keys(errors).length) {
    alert("password validation successful.");
    setError(null);
    return;
  }

  setError(errors);
};

validateForm附加到表單的onSubmit句柄。

<Form onSubmit={validateForm}>

確保您在表單中有一個 type="submit" 按鈕。

<Button
  className="mail-submit-btn"
  block
  type="submit"
  value={loading ? "Loading..." : "Login"}
>
  Submit
</Button>

更新了 stackblitz雖然我沒有帳戶,所以復制下面的更新代碼。

注意:為了簡單起見,我只是簡單地將錯誤JSON.stringify(error)為錯誤,但您會希望更優雅地呈現它。

整個 ResetPassword.js

import React, { useState } from "react";
import {
  Button,
  Form,
  FormGroup,
  Input,
  Col,
  Label,
  Modal,
  ModalHeader,
  ModalBody,
  ModalFooter
} from "reactstrap";

const useFormInput = initialValue => {
  const [value, setValue] = useState(initialValue);

  const handleChange = e => {
    setValue(e.target.value);
  };
  return {
    value,
    onChange: handleChange
  };
};

const ResetPassword = props => {
  // form inputs
  const email = useFormInput("");
  const newPassword = useFormInput("");
  const confirmPassword = useFormInput("");
  // using hooks
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  const [modal, setModal] = useState(false);

  const toggle = () => setModal(!modal);

  const validateForm = event => {
    event.preventDefault();

    const { confirmPassword, newPassword } = event.target;
    const errors = {};

    const regex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).{8,}$/;

    if (!regex.test(newPassword.value)) {
      errors.requirementUnmet = "New password does not meet requirements.";
    }

    if (newPassword.value !== confirmPassword.value) {
      errors.passwordMismatch = "Entered passwords do not match.";
    }

    if (!Object.keys(errors).length) {
      alert("password validation successful.");
      setError(null);
      return;
    }

    setError(errors);
  };

  const handleReset = e => {
    e.preventDefault();
    setError(null);
    setLoading(true);
    // some unrelated redux code
  };

  return (
    <div className="mail-reset" id="forgotPassword">
      <div className="mail-reset-content">
        <Form onSubmit={validateForm}>
          <h3 className="form-title">Enter Information</h3>

          <FormGroup row>
            <Label for="Email" sm={2}>
              Email
            </Label>
            <Col sm={4}>
              <Input
                type="email"
                name="email"
                id="Email"
                placeholder="Email"
                aria-label="email address"
                aria-describedby="email address"
                aria-invalid="false"
                {...email}
              />
            </Col>
          </FormGroup>
          <FormGroup row>
            <Label for="newPassword" sm={2}>
              New Password
            </Label>
            <Col sm={4}>
              <Input
                type="password"
                name="password"
                id="newPassword"
                placeholder="New Password"
                aria-label="new password"
                aria-describedby="new password"
                aria-invalid="false"
                {...newPassword}
              />
            </Col>
          </FormGroup>
          <FormGroup row>
            <Label for="confirmPassword" sm={2}>
              Confirm Password
            </Label>
            <Col sm={4}>
              <Input
                type="password"
                name="confirmPassword"
                id="confirmPassword"
                placeholder="Confirm Password"
                aria-label="new password"
                aria-describedby="new password"
                aria-invalid="false"
                {...confirmPassword}
              />
            </Col>
          </FormGroup>

          <div className="modal-wrapper">
            <Col sm={{ size: 4, offset: 2 }}>
              <Button onClick={toggle} className="passwordReqBtn">
                Password Requirements
              </Button>
            </Col>
            <Modal isOpen={modal} toggle={toggle} className="mail-reset-modal">
              <ModalHeader toggle={toggle}>Password Requirements</ModalHeader>
              <ModalBody>
                Your password must contain at least one capital letter, one
                number and one lowercase letter, and it must contain at least 8
                characters
              </ModalBody>
              <ModalFooter>
                <Button onClick={toggle} className="btn-modal pull-right">
                  OK
                </Button>{" "}
              </ModalFooter>
            </Modal>
          </div>

          <div className="form-actions">
            {error && (
              <>
                <small style={{ color: "red" }}>{JSON.stringify(error)}</small>
                <br />
              </>
            )}
            <br />

            <Col lg={{ offset: 2 }} sm={{ size: 1 }}>
              <Button
                className="mail-reset-btn"
                block
                type="submit"
                value={loading ? "Loading..." : "Login"}
              >
                Submit
              </Button>
              <Button
                className="mail-reset-btn"
                block
                type="reset"
                value={loading ? "Loading..." : "Login"}
                onClick={handleReset}
              >
                Reset
              </Button>
            </Col>
          </div>
        </Form>
      </div>
    </div>
  );
};

export default ResetPassword;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM