본문 바로가기

React

[React] Form Validation check

 

 

1. validation 방법

1) 양식 제출 후 체크인 경우 

 

(1) ref 사용 

장점 : 코딩이 간결

단점 : 값 재설정이 어려움

import { useRef } from "react";

export default function Login() {
  const email = useRef();
  const password = useRef();

  function handleSubmit(event) {
    event.preventDefault();

    const enteredEmail = email.current.value;
    const enteredPassword = password.current.value;
  }

  return (
    <form onSubmit={handleSubmit}>
      <h2>Login</h2>

      <div className="control-row">
        <div className="control no-margin">
          <label htmlFor="email">Email</label>
          <input id="email" type="email" name="email" ref={email} />
        </div>

        <div className="control no-margin">
          <label htmlFor="password">Password</label>
          <input id="password" type="password" name="password" ref={password} />
        </div>
      </div>

      <p className="form-actions">
        <button className="button button-flat">Reset</button>
        <button className="button">Login</button>
      </p>
    </form>
  );
}

event.preventDefault(); : Http 양식을 전송하는 브라우저의 기본 구성을 막아, 새로고침을 막아줌

 

 

 

 

 

 

(2) new FormData();

장점 : 값이 많을 때 한번에 추출 가능

import { useState } from "react";

export default function Signup() {
  const [passwordsAreNotEqual, setPasswordAreNotEqual] = useState(false);
  function handleSubmit(event) {
    event.preventDefault();

    // name prop required
    const fd = new FormData(event.target);
    const acquisitionChannel = fd.getAll("acquisition");
    const data = Object.fromEntries(fd.entries());
    data.acquisition = acquisitionChannel;

    if (data.password !== data["confirm-password"]) {
      setPasswordAreNotEqual(true);
      return;
    }

    // event.target.reset();
  }

  return (
    <form onSubmit={handleSubmit}>
      <h2>Welcome on board!</h2>
      <p>We just need a little bit of data from you to get you started 🚀</p>

      <div className="control">
        <label htmlFor="email">Email</label>
        <input id="email" type="email" name="email" required />
      </div>

      <div className="control-row">
        <div className="control">
          <label htmlFor="password">Password</label>
          <input
            id="password"
            type="password"
            name="password"
            required
            minLength={6}
          />
        </div>

        <div className="control">
          <label htmlFor="confirm-password">Confirm Password</label>
          <input
            id="confirm-password"
            type="password"
            name="confirm-password"
          />
          <div className="control-error">
            {passwordsAreNotEqual && <p>Passwords are not equal</p>}
          </div>
        </div>
      </div>

      <hr />

      <div className="control-row">
        <div className="control">
          <label htmlFor="first-name">First Name</label>
          <input type="text" id="first-name" name="first-name" required />
        </div>

        <div className="control">
          <label htmlFor="last-name">Last Name</label>
          <input type="text" id="last-name" name="last-name" required />
        </div>
      </div>

      <div className="control">
        <label htmlFor="phone">What best describes your role?</label>
        <select id="role" name="role" required>
          <option value="student">Student</option>
          <option value="teacher">Teacher</option>
          <option value="employee">Employee</option>
          <option value="founder">Founder</option>
          <option value="other">Other</option>
        </select>
      </div>

      <fieldset>
        <legend>How did you find us?</legend>
        <div className="control">
          <input
            type="checkbox"
            id="google"
            name="acquisition"
            value="google"
          />
          <label htmlFor="google">Google</label>
        </div>

        <div className="control">
          <input
            type="checkbox"
            id="friend"
            name="acquisition"
            value="friend"
          />
          <label htmlFor="friend">Referred by friend</label>
        </div>

        <div className="control">
          <input type="checkbox" id="other" name="acquisition" value="other" />
          <label htmlFor="other">Other</label>
        </div>
      </fieldset>

      <div className="control">
        <label htmlFor="terms-and-conditions">
          <input
            type="checkbox"
            id="terms-and-conditions"
            name="terms"
            required
          />
          I agree to the terms and conditions
        </label>
      </div>

      <p className="form-actions">
        <button type="reset" className="button button-flat">
          Reset
        </button>
        <button type="submit" className="button">
          Sign up
        </button>
      </p>
    </form>
  );
}

- name prop 필수 

-  const data = Object.fromEntries(fd.entries()); 모든 값을 객체화 해서 얻을 수 있음

- const acquisitionChannel = fd.getAll("acquisition"); : 다양한 값이 있는 입력창 ex) checkbox는 Object.fromEntries(fd.entries());에 빠져있어서 따로 값을 추출함

 

(3) required와 type 활용 (내장 기능)

 <div className="control">
        <label htmlFor="email">Email</label>
        <input id="email" type="email" name="email" required />
      </div>

- Form 안에 type 지정하면 그 type에 맞는 양식인지 자동으로 확인 해줌 

- required 입력하면 필수값으로 지정되어 값이 비어있으면 warning 문구를 자동으로 띄워줌

- minLength={숫자} 입력하면 최소로 작성해야하는 글자수 를 지정 할 수 있음

 

 

2) 값이 바뀔때마다 validation 하는 경우

주의 * 사용자 기반 Validation check를 하더라도, 제출 기반의 Valication check를 넣어야 함

 

(1) useState 사용 

단점 : 오류 메시지가 이르게 보여질 수 있음

(2) Custom Hook 생성

 

컴포넌트

import { useState } from "react";
import Input from "./Input";
import { isEmail, isNotEmpty, hasMinLength } from "../util/validation.js";
import { useInput } from "../hooks/useInput";

export default function Login() {
  const {
    value: emailValue,
    handleInputChange: handleEmailChange,
    handleInputBlur: handleEmailBlur,
    hasError: emailHasError,
  } = useInput("", (value) => isEmail(value) && isNotEmpty(value));

  const {
    value: passwordValue,
    handleInputChange: handlePasswordChange,
    handleInputBlur: handlePasswordBlur,
    hasError: passwordHasError,
  } = useInput("", (value) => {
    hasMinLength(value, 6);
  });

  function handleSubmit(event) {
    event.preventDefault();

    if (emailHasError || passwordHasError) {
      return;
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <h2>Login</h2>

      <div className="control-row">
        <Input
          label="Email"
          id="email"
          type="email"
          name="email"
          onBlur={handleEmailBlur}
          onChange={handleEmailChange}
          value={emailValue}
          error={emailHasError && "Please enter a valid email"}
        />

        <Input
          label="Password"
          id="password"
          type="password"
          name="password"
          onBlur={handlePasswordBlur}
          onChange={handlePasswordChange}
          value={passwordValue}
          error={passwordHasError && "Please enter a valid password"}
        />
      </div>

      <p className="form-actions">
        <button type="reset" className="button button-flat">
          Reset
        </button>
        <button className="button">Login</button>
      </p>
    </form>
  );
}

 

 

 

useInput.js 커스텀 훅 

 

import { useState } from "react";

export function useInput(defaultValue, validationFn) {
  const [enteredValue, setEnteredValue] = useState(defaultValue);
  const [didEdit, setDidEdit] = useState(false);

  const valueIsValid = validationFn(enteredValue);

  function handleInputChange(event) {
    setEnteredValue(event.target.value);
    setDidEdit(false);
  }

  function handleInputBlur() {
    setDidEdit(true);
  }

  return {
    value: enteredValue,
    handleInputChange,
    handleInputBlur,
    hasError: didEdit && !valueIsValid,
  };
}

 

(3) Library사용

- React Hook Form 

- Formik

 

 

 

2. form reset 방법

1) form 내에 type=reset 버튼을 추가

 <button type="reset" className="button button-flat">
          Reset
        </button>

 

2) submit handler에 event.target.reset(); 

 function handleSubmit(event) {
    event.preventDefault();

    // name prop required
    const fd = new FormData(event.target);
    const acquisitionChannel = fd.getAll("acquisition");
    const data = Object.fromEntries(fd.entries());
    data.acquisition = acquisitionChannel;

    if (data.password !== data["confirm-password"]) {
      setPasswordAreNotEqual(true);
      return;
    }

    // event.target.reset();
  }

 

 

 

 

 

 

'React' 카테고리의 다른 글

[React] router  (0) 2024.04.23
[React] Redux  (0) 2024.04.19
[React] Custom Hook  (0) 2024.04.17
[React] Http 연결, fetch  (0) 2024.04.16
[React] memo, useMemo  (0) 2024.04.11