[React] Form, 유효성검사

정호·2024년 3월 29일
0

TIL

목록 보기
11/19

Form

보통 입력창의 집합

label이랑 같이 쓰임

  • 양식 제출 관리 ,입력한 값 추출
  • 사용자 제공 데이터 검증하는 작업
export default function Login() {
  return (
    <form>
      <h2>Login</h2>

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

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

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

htmlFor: label을 클릭하면 시각적으로 라벨을 클릭하면 연결된 입력 요소가 활성화

form안에 있는 버튼은 양식을 제출하는 용도로 쓰임

-> 페이지가 새로고침됨

첫번째 방법
button type지정

       <button type="button" className="button" onClick={handleSubmit}>

두번째 방법
type 지정 x form에 submit 이벤트
event.preventDefault(); 이벤트 동작을 취소하는 메서드 페이지 로드 방지

    <form onSubmit={handleSubmit}>
      
 export default function Login() {
  function handleSubmit(event) {
    event.preventDefault();
  }

js 객체 속성 업데이트

ex)

//초기값
 const [enteredValues, setEnteredValue] = useState({
    email: "",
    password: "",
  });


  function handleInputChange(identifier, value) {
    setEnteredEmail((prev) => ({ ...prev, [identifier]: value }));
  }

     onChange={(event) => handleInputChange("email", event.target.value)}

[identifier]는 배열이 아니라, 객체의 속성(key)을 동적으로 설정하는 JavaScript의 문법 객체의 속성에 접근할 때 동적으로 속성을 지정하려면 대괄호 표기법([])을 사용

state통한 관리(Login)

import { useState } from 'react';

export default function Login() {
  // const [enteredEmail, setEnteredEmail] = useState('');
  // const [enteredPassword, setEnteredPassword] = useState('');
  const [enteredValues, setEnteredValues] = useState({
    email: '',
    password: '',
  });

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

    console.log(enteredValues);
  }

  function handleInputChange(identifier, value) {
    setEnteredValues((prevValues) => ({
      ...prevValues,
      [identifier]: value,
    }));
  }

  // function handleEmailChange(event) {
  //   setEnteredEmail(event.target.value);
  // }

  // function handlePasswordChange(event) {
  //   setEnteredPassword(event.target.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"
            onChange={(event) => handleInputChange('email', event.target.value)}
            value={enteredValues.email}
          />
        </div>

        <div className="control no-margin">
          <label htmlFor="password">Password</label>
          <input
            id="password"
            type="password"
            name="password"
            onChange={(event) =>
              handleInputChange('password', event.target.value)
            }
            value={enteredValues.password}
          />
        </div>
      </div>

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

useRef

참조를 만들어서 참조 속성과 연결해서 값을 추출하기만 하면됨 current가 실제 연결된 값을 갖고 있음

  • 복잡한 로직이면 많은 참조를 만들어서 하나하나 연결해야돼서 번거로울 수 있음
    const enteredEmail = email.current.value;
     <input id="email" type="email" name="email" ref={email} />

useRef통한 관리

import { useRef } from "react";

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

  function handleSubmit(event) {
    event.preventDefault();
    //current가 실제 연결된 값을 갖고있음

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

    console.log(enteredEmail, enteredPassword);
  }

  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>
  );
}

FormData(복잡한양식)

브라우저 내장함수, 양식에 입력된 각기 다른 값들을 쉽게 얻을 수 있음

  • 모든 입력창name 속성이 있어야한다.
  • FormData 객체에서 불러낸 Entry메소드의 결과를 fromEntries객체로 보냄 -> 모든 입력창과 값들의 배열을 제공
export default function Signup() {
  function handleSubmit(event) {
    event.preventDefault();

    const fd = new FormData(event.target);
    const acquisitionChannel = fd.getAll("acquisition"); //같은 이름을 가진 값을 얻으려면(배열로 저장)
    const data = Object.fromEntries(fd.entries());
    data.aquisition = acquisitionChannel;
  }

Form 초기화

type = "reset"

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

버튼 타입에 reset주는 방법

event.target활용

 event.target.reset();

state로 관리할경우

초기값으로 만들기

  const [enteredValues, setEnteredValue] = useState({
    email: "",
    password: "",
  });

  function handleSubmit(event) {
    event.preventDefault();
	setEnteredValues({
		email:"",
  		password"",
})
  }

ref로 관리할경우 (추천 x)

직접 참조값을 초기화하는것은 위험

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

  function handleSubmit(event) {
    event.preventDefault();
    //current가 실제 연결된 값을 갖고있음

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

    console.log(enteredEmail, enteredPassword);
    email.current.value = "";
  }

유효성 검사

매 키에 반응

Form에서 ref나 빌트인 Formdata를 이용했을때는 매 키 입력이 아닌 Form이 제출된 후에 데이터를 얻음 따라서 State접근법을때 사용

  const [didEdit, setDidEdit] = useState({
    email: false,
    password: false,
  });


  function handleInputBlur(identifier) {
    setDidEdit((prevEdit) => ({
      ...prevEdit,
      [identifier]: true,
    }));
  }

 <input
            id="email"
            type="email"
            name="email"
            onBlur={() => handleInputBlur("email")}
            onChange={(event) => handleInputChange("email", event.target.value)}
            value={enteredValues.email}
          />

required

type에 맞춰서 required가 적용됨

       <input
            id="password"
            type="password"
            name="password"
            required
            minLength={4}	//최소 4글자
          />
profile
열심히 기록할 예정🙃

0개의 댓글