useActionState는 액션의 결과와 대기 상태를 함께 관리해. 제출할 때마다 수동으로 로딩 flag를 켰다 끄는 코드를 줄여 보자.
시그니처
const [state, formAction, isPending] = useActionState(actionFn, initialState)에서 actionFn은 (prevState, formData) => Promise<newState> 모양이야. 훅은 다음 세 값을 반환해.
- state: 첫 렌더링에는
initialState, 이후에는 마지막 액션이 반환한 최신 상태야. - formAction:
<form action={...}>에 바로 연결할 수 있도록 감싼 함수야. - isPending: 액션이 진행 중일 때
true가 돼.
reducer와 닮은 액션
actionFn은 FormData까지 받는 reducer와 비슷해. 첫 번째 인자는 이전 상태고 두 번째 인자는 제출된 FormData야. 함수가 반환한 값이나 프로미스가 이행된 값이 다음 상태가 돼.
이 구조에서는 오류와 성공이 같은 반환 경로를 사용해. 유효성 검사에 실패하면 사용자가 입력한 값을 보존한 { error: '...', input: ... }을 반환하고, 성공하면 { data: ... }를 반환할 수 있어. 컴포넌트는 그 상태를 보고 다음 화면을 렌더링해.
이전 입력을 상태에 보존하는 패턴
서버 검증에 실패했을 때 form과 사용자의 입력을 다시 보여 주려면, 제출된 값을 오류 상태에 함께 담아 반환해. 그런 다음 uncontrolled input의 defaultValue에 상태의 입력 필드를 연결하면 React가 값을 다시 채울 수 있어.
useActionState와 useState의 경계
useState는 임의의 UI 상태와 setter를 제공해. useActionState는 하나의 액션이 거치는 대기, 성공, 실패 흐름에 상태를 묶어. draft나 토글 같은 클라이언트 UI에는 useState를 쓰고, 제출이 만드는 상태에는 useActionState를 쓰면 역할이 선명해져.