조아마시

쓸모 있는 상세페이지 만들기

웹개발/reactjs

리액트 + 타입스크립트 기초 9단계 : 실제 사용자 경험을 위한 폼 통합 시나리오

joamashi 2025. 4. 14. 18:27
반응형

핵심 주제:

  • 모달 안의 폼 처리
  • 제출 후 초기화
  • API 연동 통합 처리
  • 제출 성공/실패 메시지 관리

1. 모달 안에서 폼 처리하기 (with React Hook Form)

import { useForm } from 'react-hook-form';

interface ModalFormProps {
  onClose: () => void;
}

type FormValues = {
  email: string;
};

function ModalForm({ onClose }: ModalFormProps) {
  const {
    register,
    handleSubmit,
    reset,
    formState: { isSubmitSuccessful },
  } = useForm<FormValues>();

  const onSubmit = (data: FormValues) => {
    console.log('제출된 데이터:', data);
    reset(); // 제출 후 초기화
    onClose(); // 모달 닫기
  };

  return (
    <div className="modal">
      <form onSubmit={handleSubmit(onSubmit)}>
        <input {...register('email')} placeholder="이메일 입력" />
        <button type="submit">제출</button>
        <button type="button" onClick={onClose}>
          닫기
        </button>
      </form>
    </div>
  );
}

✅ reset()으로 입력값 초기화
✅ onClose()로 부모 컴포넌트에서 모달 닫기


2. 제출 후 상태 메시지 관리 (isSubmitSuccessful, isSubmitting, error)

function FeedbackForm() {
  const {
    register,
    handleSubmit,
    reset,
    formState: { isSubmitting, isSubmitSuccessful },
  } = useForm<{ message: string }>();

  const onSubmit = async (data: { message: string }) => {
    await new Promise((res) => setTimeout(res, 1000)); // 서버 요청 대체
    console.log('서버 응답 완료');
    reset();
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <textarea {...register('message')} placeholder="의견을 남겨주세요" />
      <button type="submit" disabled={isSubmitting}>
        {isSubmitting ? '전송 중...' : '제출'}
      </button>
      {isSubmitSuccessful && <p>제출되었습니다. 감사합니다!</p>}
    </form>
  );
}

✅ isSubmitting, isSubmitSuccessful 등 상태 관리 쉽게 가능
✅ UX 향상을 위한 "전송 중…" 표시도 자동 관리 가능


3. API 연동 예시 + 에러 처리

import { useForm } from 'react-hook-form';

async function submitToServer(data: { email: string }) {
  const res = await fetch('/api/subscribe', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data),
  });

  if (!res.ok) {
    const err = await res.json();
    throw new Error(err.message || '서버 오류');
  }
}

function SubscribeForm() {
  const {
    register,
    handleSubmit,
    reset,
    setError,
    formState: { errors, isSubmitting },
  } = useForm<{ email: string }>();

  const onSubmit = async (data: { email: string }) => {
    try {
      await submitToServer(data);
      reset();
      alert('구독 성공!');
    } catch (err: any) {
      setError('email', { message: err.message });
    }
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register('email')} placeholder="이메일" />
      {errors.email && <p>{errors.email.message}</p>}
      <button type="submit" disabled={isSubmitting}>제출</button>
    </form>
  );
}

✅ setError()를 사용해 서버에서 받은 에러를 입력 필드에 반영
✅ API 요청 → 에러 처리 → 상태 초기화까지 전체 흐름 통합


✅ 요약

reset() 제출 후 입력값 초기화
isSubmitting, isSubmitSuccessful 제출 상태 자동 관리
setError() 서버 에러 메시지를 필드에 매핑
모달 내 폼 props를 통해 닫기, 제출 상태 처리

 

728x90
반응형