Next.js/렌더링/Lesson 08
Optimistic UI — useActionState + useFormStatus + useOptimistic
35분·theory
이 챕터
5/5
TypeScript
Optimistic UI — useActionState + useFormStatus + useOptimistic
💡 왜 배워야 할까요? — '클릭 후 잠깐 멈춤' 이 사라진다
🎯
좋아요 버튼 누르면 서버 응답 200~500ms 기다린 후 UI 가 바뀌면 사용자는 '눌렸나?' 의심합니다.
💼
Optimistic UI: 클릭 즉시 UI 를 '성공한 것처럼' 보여주고, 서버 응답 오면 진실 반영. 실패하면 자동 롤백.
⚡
React 19 의 `useOptimistic` hook 으로 이 패턴이 표준화됨 — Twitter·Instagram 의 좋아요 같은 즉시 반응 UX.
🔗
`useActionState` (구 useFormState) + `useFormStatus` + `useOptimistic` 세 hook 이 Server Action 의 폼 UX 를 완성.
📈
사용자 체감: 클릭 즉시 반응 → 진짜 빠른 앱 느낌.
🏢 실무에서는
좋아요·북마크·팔로우·장바구니 추가 — 사용자가 매일 수십 번 클릭하는 액션들. 매번 0.3초 멈춤이 누적되면 '느린 사이트' 인상. useOptimistic 으로 클릭 즉시 카운트 +1 표시, 서버에서 진짜 결과 받으면 일치 확인. 실패면 -1 자동 롤백 + 에러 메시지.
3가지 hook — 역할 분담
1. 세 가지 hook 의 역할
2. useActionState (React 19 — 구 useFormState 대체)
Action 의 시그니처가 (prevState, formData) => newState 로 바뀜.
3. useFormStatus — 자식이 부모 form 상태 읽기
부모 <form> 안 어디든 위치하면 자동으로 그 form 의 상태를 받음. props drilling X.
4. useOptimistic — 즉시 UI 업데이트 + 자동 롤백
5. 셋 다 같이 — 완성된 폼
💡 💡 Optimistic UI 실전 5
1. useOptimistic 은 startTransition 안에서 호출
Transition 없이 호출하면 동기 업데이트라 효과 약함.
2. optimistic 항목에 pending: true 같은 표식 두기
사용자에게 '아직 서버 확인 안 됐다' 시각 신호 (opacity 0.5, '전송 중' 라벨).
3. 실패 시 별도 코드 불필요 — React 가 자동 롤백
Server Action 이 throw 하면 optimistic state 폐기, 원래 값 복원. catch 에서 에러 토스트만 추가하면 됨.
4. revalidatePath 후 진짜 값이 도착하면 자동 동기화
Server Action 끝에 revalidatePath 호출 → 페이지 데이터 재조회 → useOptimistic 의 initial 값 갱신 → optimistic 자동 폐기.
5. useActionState 와 함께 — 폼 전체 상태 관리
⚡ 직접 실행해보기 — Optimistic UI 시나리오
성공·실패 케이스에서 optimistic state 가 어떻게 동작하는지 시뮬레이션.
✏️ JS 코드
📟 콘솔 출력
▶ 실행 버튼을 눌러보세요
⚠️ 브라우저 샌드박스에서 실행 — console.log()만 지원, alert/fetch 불가
확인 퀴즈
Server Action 호출 후 서버 응답이 실패하면 useOptimistic 의 값은?
먼저 읽으면 좋은 개념: Streaming + Suspense — 점진적 HTML 스트리밍