리액트에서 폼(Form)을 다루는 것은 단순히 입력값을 받는 것을 넘어, 사용자의 상호작용을 상태(State)로 변환하고 이를 안전하게 서버로 전달하는 일련의 과정을 의미한다. 오늘은 리액트 폼 처리의 핵심 원리와 효율적인 데이터 흐름 설계법을 정리해 본다.

1. 리액트에서의 폼 처리: 핵심은 ‘이벤트’와 ‘상태’
리액트에서 폼은 일반적인 다른 컴포넌트와 유사한 방식으로 관리된다. 특별한 처리 방식이 따로 존재하기보다는, 이벤트와 이벤트 핸들러를 사용하여 데이터를 필요한 곳에 전달하는 방식을 취한다. 가장 빈번하게 사용되는 이벤트는 다음과 같다.
-
onChange: 요소의 입력값이 변경될 때 발생하며,
event.target.value를 통해 새로운 입력값을 알아낼 수 있다. -
onClick: 사용자가 폼 요소를 클릭할 때 발생하며, 주로 버튼 제출 시 활용된다.
리액트는 브라우저 간의 이벤트 차이를 신경 쓰지 않도록 **합성 이벤트(Synthetic Event)**를 제공하여 개발자가 앱 로직 개발에만 집중할 수 있게 도와준다.
2. 제어 컴포넌트 vs 제어되지 않는 컴포넌트
폼 데이터를 다룰 때 가장 중요한 선택은 컴포넌트를 제어(Controlled)할 것인지, 제어되지 않는(Uncontrolled) 상태로 둘 것인지 결정하는 것이다.
-
제어 컴포넌트 (Controlled Component): 리액트의 상태(State)를 폼 요소의 값(value)으로 설정하고 관리하는 방식이다. 입력값이 변경될 때마다 리액트가 이를 감지하고 상태를 갱신하며, 이 상태가 다시 폼 요소에 반영된다. 이는 데이터 동기화를 보장하는 가장 보편적인 방법이다.
-
제어되지 않는 컴포넌트 (Uncontrolled Component): 리액트 상태 대신 DOM 자체에서 데이터를 직접 관리하는 방식이다. 보통
ref를 통해 필요할 때만 DOM에서 값을 가져오며, 리액트 외부에서 상태가 관리된다는 차이점이 있다.
3. 데이터 유효성 검사와 검증 (Validation & Verification)
사용자가 입력한 데이터가 올바른 형식인지, 그리고 안전한지 확인하는 과정은 매우 중요하다. 이는 데이터의 무결성을 확보하고 보안 허점을 방지하기 위함이다.
-
유효성 검사 (Validation): 사용자가 입력한 값이 정의된 규칙(예: 최대 글자 수, 이메일 형식)을 만족하는지 확인하는 과정이다. 예를 들어, 포스트 작성 시 글자 수를 280자로 제한하는 로직이 해당된다.
-
데이터 검증 (Verification): 보안을 고려하여 부적절한 데이터가 저장되지 않도록 확인하는 작업이다. 특정 모듈을 사용하여 불쾌감을 주는 단어를 필터링하거나 비속어를 별표(*)로 변환하는 처리가 포함된다.
4. 새 포스트를 생성하는 6단계 흐름
리액트에서 폼을 통해 새로운 데이터를 생성하고 서버로 전송하는 전체 과정은 보통 다음과 같은 순서로 진행된다.
-
상태 갱신: 사용자가 입력한 데이터를 바탕으로 컴포넌트의 상태(State)를 업데이트한다.
-
검사 수행: 유효성 검사 및 콘텐츠 검증 로직을 실행한다.
-
부모 전달: 속성(Props)을 통해 전달받은 이벤트 핸들러 함수를 호출하여 데이터를 부모 컴포넌트로 전달한다.
-
상태 재설정: 데이터 전송 후 컴포넌트의 입력 필드 상태를 초기화한다.
-
서버 전송: 부모 컴포넌트에서 전달받은 데이터를 이용해 HTTP POST 요청을 서버에 보낸다.
-
로컬 UI 갱신: 서버 응답을 받은 후, 새로운 데이터를 로컬 상태에 반영하여 화면을 업데이트한다.
리액트에서 폼을 다루는 것은 결국 컴포넌트 간의 역할을 분리하고 데이터를 안전하게 흐르게 만드는 과정이다. 부모 컴포넌트가 데이터 처리를 담당하고, 자식 컴포넌트(폼)는 인터페이스 구성에 집중함으로써 결합도를 낮추고 유지보수성을 높일 수 있다. 이러한 체계적인 폼 관리는 애플리케이션의 안정성과 사용자 경험을 결정짓는 핵심 요소가 된다.