Post

NextJS 서버 액션(Server Actions)

서버 액션 실행 모델, 폼 흐름, useFormState/useFormStatus, 낙관적 업데이트와 제약사항 정리

NextJS 서버 액션(Server Actions)

API Route의 대체가 아니라, “요청-처리-UI”를 재구성하는 추상화

서버 액션을 처음 접하면 대부분 이렇게 이해한다.

“API Route를 더 간단하게 만든 기능”

이 이해는 절반만 맞고, 절반은 틀리다.
서버 액션은 API Route를 대체하는 것이 아니라,
UI 중심 애플리케이션에서 서버 요청을 다루는 방식을 바꾼 추상화다.

이 글은 서버 액션의 문법이 아니라,
어떤 문제를 해결하려고 등장했는지를 중심으로 설명한다.


1. 서버 액션의 실행 모델

“요청을 보내는 코드”가 아니라 “서버에서 실행되는 함수”

❌ 잘못된 이해

  • 서버 액션 = API Route를 감춘 함수
  • 클라이언트에서 호출되는 서버 함수

이 관점에서는 서버 액션의 설계 의도가 보이지 않는다.


✅ 올바른 이해

서버 액션은 다음 특징을 가진다.

  • 항상 서버에서 실행
  • 클라이언트는 “요청 트리거” 역할만 수행
  • 실행 결과는 UI 렌더링 흐름으로 다시 합류

즉, 서버 액션은
요청 → 처리 → UI 반영을 하나의 React 흐름 안으로 끌어온다.

중요한 점:

  • fetch를 직접 호출하지 않는다
  • JSON 응답을 직접 파싱하지 않는다
  • “네트워크 레이어”를 의식하지 않게 만든다

👉 서버 액션은 서버 로직을 UI 생명주기에 결합한다.


2. 폼 처리 흐름의 변화

기존 방식 vs 서버 액션

❌ 기존 React + API Route 흐름

  1. 폼 제출
  2. fetch 호출
  3. API Route 실행
  4. JSON 응답
  5. 클라이언트 상태 갱신
  6. UI 업데이트

문제:

  • 네트워크 로직과 UI 로직이 분리
  • 에러 처리 분산
  • 상태 관리 복잡도 증가

✅ 서버 액션 기반 흐름

  1. 폼 제출
  2. 서버 액션 실행
  3. 서버에서 데이터 처리
  4. 캐시 무효화 / 재렌더링
  5. UI 자동 반영

핵심 변화는 이것이다.

“응답을 처리한다”가 아니라
“다시 렌더링한다”

서버 액션은
HTTP 응답을 UI 상태로 번역하는 단계를 제거한다.


3. useFormState / useFormStatus의 역할

“폼 UX를 서버 중심으로 재구성”

서버 액션은 비동기 요청이기 때문에
사용자 피드백이 반드시 필요하다.

이를 위해 등장한 것이 두 훅이다.


useFormStatus

현재 폼 제출 상태를 알려주는 훅

  • pending 여부
  • 제출 중 UI 제어

정신 모델:

“지금 서버 액션이 실행 중인가?”

이 훅은

  • 전역 상태 ❌
  • 로컬 UI 상태 ⭕

로 설계되었다.


useFormState

서버 액션의 결과를 UI로 전달

  • 서버에서 반환한 값 수신
  • 유효성 에러, 메시지 처리

중요한 점:

  • 서버 액션의 반환값은 UI의 일부
  • 별도 API 응답 처리 로직 불필요

👉 이 두 훅은
폼 상태를 클라이언트 상태가 아니라 ‘서버 실행 결과’로 관리하게 만든다.


4. Optimistic Update

“응답을 기다리지 않고, 결과를 가정한다”

서버 액션은 서버에서 실행되기 때문에
기본적으로는 응답 후 UI 반영 구조다.

하지만 UX 상 즉각적인 반응이 필요한 경우가 있다.

여기서 등장하는 개념이 Optimistic Update다.


Optimistic Update의 정신 모델

“이 요청은 성공할 가능성이 높다”
UI를 먼저 바꾼다

  • 사용자 입력 즉시 반영
  • 서버 실패 시 롤백

서버 액션과 결합되면:

  • 낙관적 UI
  • 서버 액션 실행
  • 캐시 재검증으로 최종 동기화

👉 중요한 점은
낙관적 업데이트는 서버 액션을 대체하지 않는다.
서버 액션은 여전히 단일 진실 소스다.


5. 서버 액션의 제약과 한계

반드시 알고 써야 하는 부분

서버 액션은 만능이 아니다.

구조적 제약

  • 항상 서버에서 실행
  • 브라우저 API 접근 불가
  • 장시간 실행 작업에 부적합

설계적 제약

  • 범용 API 엔드포인트로 사용 ❌
  • 외부 클라이언트 접근 ❌
  • 모바일/외부 서비스용 API ❌

👉 서버 액션은
NextJS 앱 내부 UI 요청 전용 추상화다.


흔한 오해에서 오는 안티패턴

  1. 서버 액션을 REST API처럼 설계
  2. 모든 요청을 서버 액션으로 몰아넣기
  3. 에러 처리를 클라이언트 상태로 분리
  4. optimistic update를 기본값으로 사용

이 패턴들은
서버 액션의 장점을 스스로 제거한다.


최종 정리: 서버 액션 사고 체크리스트

  • 이 요청은 UI에서 직접 발생하는가?
  • 외부 클라이언트가 이 엔드포인트를 호출해야 하는가?
  • 응답을 “처리”할 필요가 있는가, “렌더링”하면 되는가?
  • 이 로직은 서버에서 실행되어야 안전한가?
  • 캐시 무효화 흐름과 자연스럽게 연결되는가?

결론: 서버 액션은 “서버 호출”이 아니라 “UI 흐름의 일부”다

서버 액션은
API Route를 없애기 위한 기능이 아니다.

  • 요청
  • 처리
  • 캐시
  • UI 반영

이 네 단계를
하나의 React 렌더링 사이클로 묶기 위한 추상화다.

서버 액션을 잘 쓴다는 것은
서버 코드를 줄이는 것이 아니라,
UI와 서버 사이의 경계를 명확히 그리는 것이다.


This post is licensed under CC BY 4.0 by the author.