Notice
Recent Posts
Recent Comments
Link
«   2025/10   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

죽이죽이

React : Form 유효성 검사 3가지 방식 본문

React

React : Form 유효성 검사 3가지 방식

죽이죽이 2024. 2. 26. 13:09

폼 제출 시 (Submit)

※ 설명
- 입력을 완전히 마친 후 제출을 하기 전까지 경고를 표시하지 않는다.

- 불필요한 피드백은 줄지만, 피드백이 너무 늦을 수 있다.

※ 예시 코드
import { useRef, useState } from "react";

const SimpleInput = (props) => {
  const nameRef = useRef();
  const [name, setName] = useState("");
  const [nameValid, setNameValid] = useState({
    isNotEmpty: false,
    isTouched: false,
  });

  const nameInputHandler = (e) => {
    setName(e.target.value);
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    setNameValid((prev) => ({ ...prev, isTouched: true }));

    if (!name.trim()) {
      console.log("submit fail");
      setNameValid((prev) => ({ ...prev, isNotEmpty: false }));
      return;
    }

    setNameValid((prev) => ({ ...prev, isNotEmpty: true }));
    setName("");
  };

  const isNameValid = !nameValid.isNotEmpty && nameValid.isTouched;
  const formClasses = isNameValid ? "form-control invalid" : "form-control";

  return (
    <form onSubmit={handleSubmit}>
      <div className={formClasses}>
        <label htmlFor="name">당신의 이름은?</label>
        <input type="text" id="name" ref={nameRef} value={name} onChange={nameInputHandler} />
        {isNameValid && <p className="error-text">이름값은 빈 값이 아니어야 됩니다.</p>}
      </div>
      <div className="form-actions">
        <button>제출하기</button>
      </div>
    </form>
  );
};

export default SimpleInput;

 

 

 

초점 잃을 때 (lose focus)

설명
- 하나의 input에 대해 입력을 완전히 마치고 Blur 되기 전까지 경고를 표시하지 않는다.
- 적당한 수준의 피드백이 주어져서 많이 선호된다.

예시 코드
import { useRef, useState } from "react";

const SimpleInput = (props) => {
  const nameRef = useRef();
  const [name, setName] = useState("");
  const [nameValid, setNameValid] = useState({
    isNotEmpty: false,
    isTouched: false,
  });

  const nameInputChangeHandler = (e) => {
    setName(e.target.value);
  };

  // 초점을 잃었을 경우
  const nameInputBlurHandler = () => {
    setNameValid((prev) => ({ ...prev, isTouched: true }));

    if (name.trim() === "") {
      setNameValid((prev) => ({ ...prev, isNotEmpty: false }));
      return;
    }

    setNameValid((prev) => ({ ...prev, isNotEmpty: true }));
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    setNameValid((prev) => ({ ...prev, isTouched: true }));

    if (name.trim() === "") {
      console.log("submit fail");
      setNameValid((prev) => ({ ...prev, isNotEmpty: false }));
      return;
    }

    setNameValid((prev) => ({ ...prev, isNotEmpty: true }));
    setName("");
  };

  const isNameValid = !nameValid.isNotEmpty && nameValid.isTouched;
  const formClasses = isNameValid ? "form-control invalid" : "form-control";

  return (
    <form onSubmit={handleSubmit}>
      <div className={formClasses}>
        <label htmlFor="name">당신의 이름은?</label>
        <input
          type="text"
          id="name"
          ref={nameRef}
          value={name}
          onChange={nameInputChangeHandler}
          onBlur={nameInputBlurHandler} // 초점을 잃었을 경우
        />
        {isNameValid && <p className="error-text">이름값은 빈 값이 아니어야 됩니다.</p>}
      </div>
      <div className="form-actions">
        <button>제출하기</button>
      </div>
    </form>
  );
};

export default SimpleInput;

 

 

 

매 번 키보드 칠 때 (on every keystroke)

설명
- 입력하는 도중 경고가 지속적으로 발생한다.
- 올바르지 않은 형태의 값에 대해 바로 피드백을 준다.

예시 코드
import { useRef, useState } from "react";

const SimpleInput = (props) => {
  const nameRef = useRef();
  const [name, setName] = useState("");
  const [nameValid, setNameValid] = useState({
    isNotEmpty: false,
    isTouched: false,
  });

  // 사용자가 키보드 입력 시 계속 유효성 검사
  const nameInputChangeHandler = (e) => {
    setName(e.target.value);
    setNameValid((prev) => ({ ...prev, isTouched: true }));

    if (name.trim() === "") {
      setNameValid((prev) => ({ ...prev, isNotEmpty: false }));
    } else {
      setNameValid((prev) => ({ ...prev, isNotEmpty: true }));
    }
  };

  const nameInputBlurHandler = () => {
    setNameValid((prev) => ({ ...prev, isTouched: true }));

    if (name.trim() === "") {
      setNameValid((prev) => ({ ...prev, isNotEmpty: false }));
      return;
    }

    setNameValid((prev) => ({ ...prev, isNotEmpty: true }));
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    setNameValid((prev) => ({ ...prev, isTouched: true }));

    if (name.trim() === "") {
      console.log("submit fail");
      setNameValid((prev) => ({ ...prev, isNotEmpty: false }));
      return;
    }

    setNameValid((prev) => ({ ...prev, isNotEmpty: true }));
    setName("");
  };

  const isNameValid = !nameValid.isNotEmpty && nameValid.isTouched;
  const formClasses = isNameValid ? "form-control invalid" : "form-control";

  return (
    <form onSubmit={handleSubmit}>
      <div className={formClasses}>
        <label htmlFor="name">당신의 이름은?</label>
        <input
          type="text"
          id="name"
          ref={nameRef}
          value={name}
          onChange={nameInputChangeHandler}
          onBlur={nameInputBlurHandler}
        />
        {isNameValid && <p className="error-text">이름값은 빈 값이 아니어야 됩니다.</p>}
      </div>
      <div className="form-actions">
        <button>제출하기</button>
      </div>
    </form>
  );
};

export default SimpleInput;

'React' 카테고리의 다른 글

React : Redux 사용하기  (0) 2024.02.27
React : Redux란?  (0) 2024.02.26
React : Custom Hook  (0) 2024.02.23
React : debounce  (0) 2024.02.20
React : Portal  (0) 2024.02.19