이름과 import 위치가 바뀌었어
예전 react-dom의 useFormState 대신 React 19에서는 react의 useActionState를 써. 새 hook은 isPending까지 세 번째 값으로 돌려주므로, 흔한 제출 버튼 비활성화만을 위해 별도 useFormStatus를 붙일 필요가 줄었어.
세 값이 한 제출 흐름을 만든다
const [state, formAction, isPending] = useActionState(action, initialState)처럼 사용해. state는 화면에 보여 줄 최근 결과, formAction은 폼에 연결할 함수, isPending은 요청이 진행 중인지 알려 주는 값이야.
액션의 첫 인자는 이전 상태야
연결한 액션은 (prevState, formData)를 받고 다음 상태를 반환해. 성공 메시지, 필드별 검증 오류, 낙관적 표시를 되돌릴 정보가 이 통로를 지나와. 반환값의 타입을 명시하면 서버와 클라이언트가 같은 상태 모양을 공유할 수 있어.
상태는 응답이지 데이터베이스가 아니야
여기에 영구 데이터를 복제하지 말고, “이번 제출이 어떻게 끝났는가”를 표현하는 데 써. 실제 데이터는 변경 뒤 캐시를 재검증해 다시 읽는 편이 일관돼.
액션 상태를 성공·필드 오류·전체 오류처럼 구별 가능한 union으로 정의해. 그러면 렌더링 쪽은 문자열을 추측하지 않고 상태 종류에 따라 focus와 aria 설명을 이동할 수 있어. isPending 동안 중복 제출을 막되 키보드 사용자가 왜 버튼이 잠겼는지 알 수 있는 표시도 남겨. 연속 제출과 느린 응답도 시험해서 오래된 결과가 새 상태를 덮지 않는지 확인해. 대기 표시는 장식이 아니라 어떤 제출이 현재 화면을 소유하는지 보여 주는 상태야. pending이 false로 돌아왔다고 서버 데이터가 자동으로 최신이라는 뜻은 아니야. 액션이 변경 뒤 관련 캐시를 재검증하고 새 서버 결과가 렌더링되어야 실제 상태와 맞아. hook 상태에 영구 데이터를 복제하면 두 진실 사이의 동기화 문제가 생겨.
성공, 필드 오류, 서버 오류를 차례로 반환하는 액션을 연결하고 state와 isPending의 변화를 기록해. 빠르게 두 번 제출했을 때 버튼과 메시지가 어떻게 움직이는지, 캐시 재검증 뒤 실제 서버 데이터가 상태와 일치하는지도 확인해.