Frontend Study

React #12 _ Form 관리

jimmmy_jin 2025. 1. 2. 18:10

React에서 Form 데이터를 다루는 방법: Login 예제와 다양한 방식

Form 데이터를 가져와서 처리하는 작업은 React 개발에서 매우 자주 등장하는 패턴 중 하나이다. 대표적으로 로그인(Login) 폼의 경우 이메일과 비밀번호를 입력받아 데이터를 서버로 전송해야 한다. 이 글에서는 State 관리FormData API를 활용한 Form 데이터 처리 방법을 소개한다.


1. State를 활용한 Form 데이터 처리

가장 기본적인 방식은 State를 활용하여 Form 데이터를 관리하는 것이다. State를 사용하면 React의 양방향 바인딩을 통해 Input 값과 상태를 쉽게 동기화할 수 있다.

코드 예시

import { useState } from "react";

export default function Login() {
  const [enteredValue, setEnteredValue] = useState({
    email: "",
    password: "",
  });

  function handleSubmit(event) {
    event.preventDefault(); // 기본 폼 동작 방지
    console.log(enteredValue); // State에 저장된 값 출력
  }

  function handleInputChange(ident, value) {
    setEnteredValue((prevValue) => ({
      ...prevValue, // 기존 값 유지
      [ident]: value, // 새로운 값 업데이트
    }));
  }

  return (
    <form onSubmit={handleSubmit}>
      <h2>Login</h2>
      <div>
        <label htmlFor="email">Email</label>
        <input
          id="email"
          type="email"
          value={enteredValue.email}
          onChange={(event) => handleInputChange("email", event.target.value)}
        />
      </div>
      <div>
        <label htmlFor="password">Password</label>
        <input
          id="password"
          type="password"
          value={enteredValue.password}
          onChange={(event) => handleInputChange("password", event.target.value)}
        />
      </div>
      <button type="submit">Login</button>
    </form>
  );
}

핵심 포인트

  1. State 통합 관리:
    • 이메일과 비밀번호를 각각의 State로 관리할 수도 있지만, 하나의 객체로 통합하면 코드가 간결해진다.
    • useState의 객체 형태를 활용해 필드를 쉽게 업데이트할 수 있다.
  2. handleInputChange:
    • ident(필드 이름)과 value(새로운 값)를 매개변수로 받아 State를 업데이트한다.
    • 기존 값은 ...prevValue로 유지하며, 필요한 필드만 업데이트.
  3. 폼 제출:
    • event.preventDefault()로 기본 동작을 막고, enteredValue를 활용해 데이터를 출력하거나 서버로 전송한다.

2. FormData와 네이티브 브라우저 API 활용

State 대신 FormData API를 사용하여 Form 데이터를 가져올 수도 있다. 특히 FormData는 브라우저에서 기본 제공하는 객체로, Form 요소의 데이터를 빠르게 수집할 수 있다.

코드 예시

function handleSubmit(event) {
  event.preventDefault(); // 기본 폼 동작 방지

  const formData = new FormData(event.target); // Form 데이터 가져오기
  const acquisition = formData.getAll("acquisition"); // 체크박스 값 가져오기
  const data = Object.fromEntries(formData); // 모든 Form 데이터를 객체로 변환
  data.acquisition = acquisition; // 추가 데이터 병합

  console.log(data); // 최종 데이터 출력
}

핵심 포인트

  1. FormData 객체 생성:
    • new FormData(event.target)을 통해 Form 데이터를 가져온다.
    • Form 요소(event.target)에 포함된 모든 Input 값을 자동으로 수집한다.
  2. getAll 메서드:
    • 체크박스와 같은 여러 값을 가지는 필드를 가져올 때 사용.
    • 예: formData.getAll("acquisition")은 체크된 모든 값을 배열로 반환.
  3. Object.fromEntries:
    • FormData 객체를 일반 JavaScript 객체로 변환한다.
    • 예: Object.fromEntries(formData)는 { email: '...', password: '...' } 형태의 객체를 생성.
  4. 데이터 병합:
    • 수집한 데이터를 기존 객체에 추가하거나 수정하여 원하는 형태로 가공.

3. Ref를 활용한 Form 데이터 관리

Ref를 사용하면 Form 요소를 직접 참조하여 값을 가져올 수 있다. 하지만 관리해야 할 Input 필드가 많아질수록 비효율적일 수 있다.

코드 예시

import { useRef } from "react";

export default function Login() {
  const emailRef = useRef();
  const passwordRef = useRef();

  function handleSubmit(event) {
    event.preventDefault();
    console.log({
      email: emailRef.current.value,
      password: passwordRef.current.value,
    });
  }

  return (
    <form onSubmit={handleSubmit}>
      <h2>Login</h2>
      <div>
        <label htmlFor="email">Email</label>
        <input id="email" type="email" ref={emailRef} />
      </div>
      <div>
        <label htmlFor="password">Password</label>
        <input id="password" type="password" ref={passwordRef} />
      </div>
      <button type="submit">Login</button>
    </form>
  );
}

Ref의 단점

  • Input 필드가 많아질수록 모든 필드에 Ref를 추가해야 하므로 관리가 번거롭다.
  • State처럼 React의 상태 관리 기능과 양방향 바인딩을 활용할 수 없다.

5. 마무리

React에서 Form 데이터를 처리하는 방법은 다양한 시나리오에 따라 선택할 수 있다.

  • 간단한 로그인 폼: State 관리가 적합.
  • 체크박스, 파일 업로드 등 복잡한 Form: FormData API를 활용.