<form action={serverAction}> 형태로 연결하면 FormData 객체가 자동으로 전달된다. 필드가 많을 경우 Object.fromEntries(formData)로 한 번에 추출할 수 있다. 단, 이 경우 $ACTION_ 접두사가 붙은 내부 프로퍼티가 함께 포함된다.
폼이 인증된 페이지에서만 렌더링되더라도, Server Action 내부에서 반드시 인증/권한 검증을 수행해야 한다.
폼 필드 외의 데이터는 .bind(null, extraArg) 패턴으로 전달한다. Server Action은 바인딩된 인자를 FormData보다 앞선 첫 번째 인자로 받는다. <input type="hidden">으로 전달하는 방식도 있지만, 렌더링된 HTML에 값이 그대로 노출되므로 권장하지 않는다.
required, type="email" 등)으로 기본 검증을 처리한다.useActionState 훅으로 에러 메시지를 UI에 반영한다. 이때 Server Action의 첫 번째 인자가 prevState 또는 initialState로 변경된다.useActionState: [state, formAction, pending]을 반환한다. state로 에러 메시지를 표시하고, pending으로 제출 중 버튼 비활성화 처리를 한다.useFormStatus: 별도의 자식 컴포넌트를 만들어 pending 값으로 로딩 상태를 처리한다. 반드시 <form>의 자식 컴포넌트에서 사용해야 한다. React 19부터는 data, method, action 키도 추가로 제공된다. React 코어 팀은 프레임워크 자체에 태그의 상태를 백그라운드에서 추적하는 레이더를 내장했다. useFormStatus는 내부적으로 Context API를 사용하여 부모 폼의 상태를 자식 컴포넌트들에게 브로드캐스팅한다.useOptimistic 훅을 사용하면 서버 응답을 기다리지 않고 UI를 먼저 업데이트할 수 있다. 서버 처리가 완료되면 실제 데이터로 자동 동기화된다.
<button>, <input type="submit">, <input type="image"> 등 <form> 내부 중첩 요소에서 formAction prop으로 Server Action을 개별 지정할 수 있다. 하나의 폼에서 여러 Server Action을 분기 처리할 때 유용하다.
requestSubmit() 메서드를 사용하면 코드로 폼 제출을 트리거할 수 있다. 가장 가까운 <form> 조상을 찾아 해당 Server Action을 실행한다. ⌘ + Enter 단축키 처리 등에 활용할 수 있다.