formController 객체의 도구들
formController 객체에는 form을 관리하기 위한 다양한 메서드가 들어있습니다. 이 메서드들은 각각 특정한 역할을 담당하며 함께 동작하여 폼의 전체 생명주기를 관리합니다. register 함수는 입력 필드를 등록하고 이벤트 핸들러를 자동으로 연결하며, getValues와 getErrors는 현재 폼 상태와 오류 정보를 읽어올 수 있게 합니다. setValues와 setErrors를 통해 외부 데이터를 주입하거나 상태를 직접 제어할 수 있고, handleSubmit은 폼 제출 시 데이터 유효성을 검증하고 성공 시에만 콜백 함수를 실행합니다. 이러한 도구들을 활용하면 복잡한 폼 로직을 선언적이고 체계적으로 관리할 수 있어 개발 생산성과 코드 품질을 모두 향상시킬 수 있습니다.
register#
register 함수는 폼 필드를 Sicilian 폼 컨트롤러에 등록하고 필요한 이벤트 핸들러를 자동으로 연결하는 핵심 기능입니다. 아래 타입 정의에서 볼 수 있듯이, 다양한 입력 유형을 지원하며 특히 타입스크립트 환경에서 타입 안전성을 제공합니다. ExtractKeys<T> 버전은 initValue나 validator에 정의된 필드명만 허용하여 오타나 존재하지 않는 필드를 사용할 수 없게 합니다. 반면 string 버전은 동적으로 필드를 추가할 때 유연성을 제공합니다. radio 타입은 일반 입력 필드와 달리 value 속성이 필수적으로 요구되며, 이를 통해 동일한 name을 가진 여러 radio 버튼을 구분합니다. 또한 각 필드에 validate 객체를 선택적으로 제공하여 개별적인 유효성 검사 규칙을 적용할 수 있습니다.
register 함수가 반환하는 IRegister 인터페이스는 리액트 입력 요소와 통합할 수 있는 이벤트 핸들러와 속성들을 제공합니다. onChange, onBlur, onFocus 핸들러는 각각 입력값 변경, 포커스 해제, 포커스 획득 시 폼 상태를 업데이트하고 필요에 따라 유효성 검사를 실행합니다. 특히 SicilianEvent 타입을 사용하여 일반적인 DOM 이벤트뿐 아니라 커스텀 이벤트 객체도 처리할 수 있습니다. name과 id 속성은 필드 식별자로 작용하며, type 속성은 HTML 입력 요소의 타입을 지정합니다. 또한 체크박스나 라디오 버튼 같은 요소를 위한 checked 속성과 select 요소 등을 위한 value 속성도 필요에 따라 제공됩니다. 이 모든 프로퍼티는 스프레드 연산자{...register({ name: "email" })}를 통해 JSX 요소에 간편하게 적용할 수 있어 보일러플레이트 코드를 대폭 줄여줍니다.
Values and Errors#
formController는 입력 필드의 현재 값과 오류 상태에 접근하고 관리할 수 있는 다양한 메서드를 제공합니다. getValues는 폼의 모든 필드 값을 가져오거나 특정 필드의 값만 선택적으로 가져올 수 있으며, getErrors는 각 필드에 연결된 현재 오류 메시지를 조회합니다. 이 두 함수는 상태를 구독하는 방식으로 동작하여 값이 변경될 때마다 컴포넌트가 자동으로 리렌더링됩니다. setStore와 getStore는 더 낮은 수준에서 폼 상태 저장소에 직접 접근할 수 있게 해주어 복잡한 상태 관리 시나리오에서 유용합니다. 이러한 도구들을 통해 개발자는 폼 데이터를 읽고 수정하는 작업을 세밀하게 제어할 수 있으며, 외부 API로부터 받아온 데이터로 폼을 초기화하거나 특정 조건에 따라 값을 동적으로 업데이트하는 등의 고급 사용 사례를 구현할 수 있습니다.getValues와 getErrors가 리턴하는 객체는 전역 상태 그 자체이기 때문에, Context API의 리랜더링 방식과 유사한 구조적 문제를 안고 있습니다. 즉, input의 상태를 아무리 잘 격리해두었다 해도 부모 컴포넌트에 getValues 객체가 있다면 부모 컴포넌트 전체가 리랜더링됩니다. 이 문제를 해결하기 위해 getValues 함수와 getErrors 함수는 전역 상태로부터 일부만을 구독할 수 있도록 selecting name을 인자로 받습니다. 인자 없이 호출하면 전체 폼 상태 또는 오류 객체를 반환하며, 특정 필드 이름을 인자로 전달하면 해당 필드의 값이나 오류만 반환합니다.
setValues와 setErrors는 각각 폼 값과 오류 상태를 부분적으로 업데이트할 수 있게 해주며, 이러한 유연한 API 설계 덕분에 전체 폼 상태를 한번에 조회하거나 특정 필드만 선택적으로 관찰할 수 있어 성능 최적화에 도움이 됩니다.
handleSubmit#
handleSubmit 함수는 콜백 함수를 인자로 받습니다. 이 콜백 함수는 onSubmit이 발생한 시점의 전체 formState와 이벤트 객체를 인자로 받습니다. 또한 내부적으로 e.preventDefault() 처리가 되어있어 form submit으로 인한 리다이렉트가 발생하지 않습니다.
getValues 메소드로부터 전체 formState를 받아와 직접 submit 로직을 구현할 수도 있습니다. 하지만 handleSubmit을 사용하면 몇 가지 이점을 얻을 수 있습니다.
- 만약 해결되지 않은 에러 메세지가 하나라도 남아있다면
handleSubmit은 submit을 중지시킵니다. 이를 통해 원치 않는 값이 백엔드로 가는 것을 방지할 수 있습니다. - 비슷하게,
formController가 관리하는 input이 모두 비어있는 경우에도 submit을 중지시킵니다. 따라서 유저가 실수로 submit 버튼을 눌러도 http 통신이 발생하지 않습니다.
clearFormOn: ["submit"] 옵션이 제공된 상태라도 submit에 실패했다면 form이 초기화되지 않습니다.
handleServerAction#
handleServerAction 메서드는 서버 액션 혹은 서버 함수라고 불리는 상호작용을 처리하며, 폼 데이터 전송 및 응답 처리를 포함합니다. 이 메서드는 서버 측에서 실행되는 비동기 함수와 통합되어, 폼 제출 시점에 서버로 데이터를 전송하고, 서버로부터의 응답을 처리할 수 있도록 설계되었습니다.
사용자는 handleServerAction 메서드에 서버 액션 함수를 인자로 전달하며, 이 함수는 폼 데이터와 이벤트 객체를 받아 서버와의 통신을 수행합니다. 이 과정에서 폼 데이터의 유효성 검사가 자동으로 이루어지며, 검증에 실패할 경우 서버 액션이 호출되지 않습니다. 또한, 이 메서드는 서버로부터의 응답을 처리하는 콜백 함수를 추가로 인자로 받을 수 있어, 성공적인 응답이나 오류 상황에 대한 후속 작업을 쉽게 구현할 수 있습니다.
일반적인 서버 액션 함수는 FormData 객체를 인자로 받습니다. 하지만 handleServerAction 메서드는 폼 데이터를 객체 형태로 변환하여 전달합니다. 이는 서버 액션 함수 내에서 폼 데이터를 보다 직관적으로 다룰 수 있게 해주며, FormData 객체를 직접 조작하는 번거로움을 줄여줍니다. 또한, 이벤트 객체도 함께 전달되어 폼 제출과 관련된 추가적인 컨텍스트 정보를 활용할 수 있습니다.
이러한 설계를 통해 handleServerAction 메서드는 폼 제출과 서버 통신을 간소화하고, 개발자가 서버와의 상호작용을 보다 효율적으로 관리할 수 있도록 돕습니다.