icon안동민 개발노트

폼 다루기 기초


 React에서 폼을 다루는 것은 사용자 입력을 관리하고 처리하는 중요한 부분입니다.

 이 절에서는 React에서 폼을 다루는 기본적인 방법과 다양한 폼 요소를 처리하는 방법을 알아보겠습니다.

제어 컴포넌트 vs 비제어 컴포넌트

 React에서 폼 요소를 다루는 두 가지 주요 방법이 있습니다. 제어 컴포넌트와 비제어 컴포넌트.

  1. 제어 컴포넌트 (Controlled Components) 제어 컴포넌트는 React에 의해 값이 제어되는 입력 폼 요소입니다.

 장점

  • React에 의해 직접 제어되므로 상태 관리가 용이합니다.
  • 실시간으로 입력 값을 검증하거나 조작할 수 있습니다.

 단점

  • 각 입력 요소마다 상태와 핸들러를 만들어야 하므로 코드가 길어질 수 있습니다.
function ControlledForm() {
  const [inputValue, setInputValue] = useState('');
 
  const handleChange = (event) => {
    setInputValue(event.target.value);
  };
 
  return <input value={inputValue} onChange={handleChange} />;
}
  1. 비제어 컴포넌트 (Uncontrolled Components) 비제어 컴포넌트는 React 외부에서 폼 데이터가 처리되는 방식입니다.

 장점

  • 구현이 간단합니다.
  • React 상태를 사용하지 않으므로 불필요한 리렌더링을 줄일 수 있습니다.

 단점

  • 실시간으로 입력 값을 제어하기 어렵습니다.
function UncontrolledForm() {
  const inputRef = useRef(null);
 
  const handleSubmit = (event) => {
    event.preventDefault();
    console.log('Input Value:', inputRef.current.value);
  };
 
  return (
    <form onSubmit={handleSubmit}>
      <input ref={inputRef} />
      <button type="submit">Submit</button>
    </form>
  );
}

다양한 폼 요소 다루기

  1. 텍스트 입력
function TextInput() {
  const [text, setText] = useState('');
 
  return (
    <input
      type="text"
      value={text}
      onChange={(e) => setText(e.target.value)}
    />
  );
}
  1. 체크박스
function Checkbox() {
  const [isChecked, setIsChecked] = useState(false);
 
  return (
    <label>
      <input
        type="checkbox"
        checked={isChecked}
        onChange={(e) => setIsChecked(e.target.checked)}
      />
      Agree to terms
    </label>
  );
}
  1. 라디오 버튼
function RadioButtons() {
  const [selectedOption, setSelectedOption] = useState('');
 
  return (
    <div>
      <label>
        <input
          type="radio"
          value="option1"
          checked={selectedOption === 'option1'}
          onChange={(e) => setSelectedOption(e.target.value)}
        />
        Option 1
      </label>
      <label>
        <input
          type="radio"
          value="option2"
          checked={selectedOption === 'option2'}
          onChange={(e) => setSelectedOption(e.target.value)}
        />
        Option 2
      </label>
    </div>
  );
}
  1. 셀렉트 박스
function SelectBox() {
  const [selectedValue, setSelectedValue] = useState('');
 
  return (
    <select
      value={selectedValue}
      onChange={(e) => setSelectedValue(e.target.value)}
    >
      <option value="">Select an option</option>
      <option value="option1">Option 1</option>
      <option value="option2">Option 2</option>
      <option value="option3">Option 3</option>
    </select>
  );
}

폼 제출 처리

 폼 제출을 처리하려면 onSubmit 이벤트 핸들러를 사용합니다.

function LoginForm() {
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
 
  const handleSubmit = (event) => {
    event.preventDefault();
    // 폼 제출 로직 구현
    console.log('Submitted:', { username, password });
  };
 
  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={username}
        onChange={(e) => setUsername(e.target.value)}
        placeholder="Username"
      />
      <input
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        placeholder="Password"
      />
      <button type="submit">Login</button>
    </form>
  );
}

유효성 검사 기초

 React에서 폼 유효성 검사는 일반적으로 상태와 조건문을 사용하여 구현합니다.

function ValidatedForm() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [errors, setErrors] = useState({});
 
  const validateForm = () => {
    let newErrors = {};
    if (!email) newErrors.email = 'Email is required';
    if (!password) newErrors.password = 'Password is required';
    if (password.length < 6) newErrors.password = 'Password must be at least 6 characters';
    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  };
 
  const handleSubmit = (event) => {
    event.preventDefault();
    if (validateForm()) {
      // 폼 제출 로직
      console.log('Form is valid. Submitting...');
    } else {
      console.log('Form is invalid');
    }
  };
 
  return (
    <form onSubmit={handleSubmit}>
      <div>
        <input
          type="email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
          placeholder="Email"
        />
        {errors.email && <span>{errors.email}</span>}
      </div>
      <div>
        <input
          type="password"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
          placeholder="Password"
        />
        {errors.password && <span>{errors.password}</span>}
      </div>
      <button type="submit">Submit</button>
    </form>
  );
}

 이 예제에서는 간단한 이메일과 비밀번호 유효성 검사를 구현했습니다. validateForm 함수는 입력값을 검사하고 오류 메시지를 설정합니다.

폼 라이브러리 소개

 복잡한 폼을 다룰 때는 Formik, React Hook Form과 같은 라이브러리를 사용하면 유용합니다. 이러한 라이브러리는 폼 상태 관리, 유효성 검사, 제출 처리 등을 간소화해줍니다.

 예를 들어, React Hook Form을 사용한 간단한 예제는 다음과 같습니다.

import { useForm } from 'react-hook-form';
 
function HookForm() {
  const { register, handleSubmit, errors } = useForm();
  const onSubmit = data => console.log(data);
 
  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input name="email" ref={register({ required: true })} />
      {errors.email && <span>This field is required</span>}
      <input name="password" type="password" ref={register({ required: true, minLength: 6 })} />
      {errors.password && <span>Password must be at least 6 characters</span>}
      <button type="submit">Submit</button>
    </form>
  );
}

 React에서 폼을 다루는 것은 사용자 입력을 관리하고 상호작용하는 중요한 부분입니다.

 제어 컴포넌트와 비제어 컴포넌트의 개념을 이해하고, 다양한 폼 요소를 적절히 다루는 방법을 익히는 것이 중요합니다.

 또한 폼 제출 처리와 유효성 검사를 구현하여 사용자 경험을 향상시킬 수 있습니다.

 복잡한 폼 처리가 필요한 경우 전문 라이브러리의 사용을 고려해보는 것도 좋은 방법입니다.

 이러한 기술들을 적절히 활용하면 사용자 친화적이고 효율적인 폼을 구현할 수 있습니다.