서버 액션 (Server Action)

Frontend/Next.js

서버 액션이란?

서버 액션은 Next.js에서 제공하는 기능으로, 브라우저에서 직접 호출할 수 있는 서버 측 비동기 함수이다. 이를 통해 별도의 API 엔드포인트를 만들지 않고도 클라이언트에서 서버 측 로직을 실행할 수 있다.

서버 액션을 사용하려면 함수 내부에 "use server" 지시어를 추가하면 된다.

export default function Page() {
  const saveName = async (formData: FormData) => {
    "use server";

    const name = formData.get("name");
    await sql`INSERT INTO Names (name) VALUES (${name})`;
  };

  return (
    <form action={saveName}>
      <input name="name" />
      <button type="submit">제출</button>
    </form>
  );
};
  • saveName 함수는 서버 액션으로 정의됨
  • 폼 제출 시 이 함수가 서버에서 실행됨
  • 클라이언트에서 직접 데이터베이스 쿼리를 실행하지 않아 보안이 강화됨

 

재검증 방식

서버 액션 실행 후 데이터 변경을 화면에 반영하기 위해 Next.js는 다양한 재검증 방식을 제공한다.

revalidatePath

특정 경로의 캐시를 무효화하고 데이터를 다시 가져오도록 한다.

import { revalidatePath } from "next/cache";

export async function createReviewAction(formData: FormData) {
  // 서버 액션 로직..
  revalidatePath(`/book/${bookId}`);
};

revalidatePath의 다양한 사용방법

1. 특정 주소에 해당하는 페이지만 재검증

revalidatePath(`/book/${bookId}`);

2. 특정 경로의 모든 동적 페이지를 재검증

revalidatePath('/book/[id]', 'page');

3. 특정 레이아웃을 갖는 모든 페이지 재검증

revalidatePath('/(with-searchbar)', 'layout');

4. 모든 데이터 재검증

revalidatePath('/', 'layout');

 

revalidatePath 사용 시 주의사항

  • 서버 컴포넌트 또는 서버 액션 내부에서만 호출 가능하다.
  • 해당 경로의 페이지 전체가 재검증된다.
    즉, 페이지 내 모든 컴포넌트가 재렌더링되며 데이터 페칭도 다시 수행된다.
  • 데이터 캐시와 풀 라우트 매시가 모두 삭제된다.
    (cache: 'force-cache' 설정이 있어도 무효화)
  • generateStaticParams로 생성된 정적 페이지에도 영향을 미친다.
    • 재검증 직후에는 새 데이터가 페이지에 반영되지만, 풀 라우트 캐시는 갱신되지 않는다.
    • 다음 페이지 방문 시 동적 렌더링이 발생하며, 이때 풀 라우트 캐시가 최신 데이터로 업데이트된다.

 

revalidateTag

태그 값을 기준으로 데이터 캐시를 재검증한다. 페이지 전체가 아닌 특정 데이터만 선택적으로 재검증할 수 있다.

import { revalidateTag } from "next/cache";

export async function createReviewAction(formData: FormData) {
  // 서버 액션 로직...
  revalidateTag(`review-${bookId}`);
};
// 데이터 페칭 시 next.tags 옵션을 사용하여 해당 데이터에 태그를 지정해야 한다.

async function fetchReviews(bookId: string) {
  const response = await fetch(`/api/reviews/${bookId}`, {
    next: { tags: [`review-${bookId}`] } // 데이터에 태그 지정
  });
  // 응답 처리 로직...
};

 

클라이언트 컴포넌트에서의 서버 액션

useActionState 훅

React 19에서 추가된 useActionState 훅은 form 태그의 상태를 쉽게 핸들링할 수 있게 해준다.

const [state, formAction, isPending] = useActionState(createReviewAction, null);
<form action={formAction}>
  {/* 폼 내용 */}
</form>

 

서버 액션 구현

"use server";
export async function createReviewAction(state: any, formData: FormData) {
  // formData에서 필요한 데이터 추출
  try {
    // API 호출 또는 데이터 처리 로직
    return { status: true, error: "" };
  } catch (err) {
    return { status: false, error: `에러 메시지: ${err}` };
  }
};

 

isPending 활용

다음과 같이 서버 액션 실행 중 상태를 표시하고, UI 요소의 동작을 제어할 수 있다.

<button disabled={isPending} type="submit">
  {isPending ? "..." : "작성하기"}
</button>
  • 버튼의 텍스트를 동적으로 변경
  • 서버 액션 실행 중에는 버튼을 비활성화

 

에러 핸들링

다음과 같이 서버 액션의 결과에 따른 에러 처리를 할 수 있다.

useEffect(() => {
  if (state && !state.status) alert(state.error);
}, [state]);

'Frontend > Next.js' 카테고리의 다른 글

Next.js의 이미지 최적화  (0) 2025.11.13
Next.js 앱 라우터 고급 라우팅 패턴  (0) 2025.11.13
Next.js 앱 라우터의 에러 핸들링  (0) 2025.11.13
스트리밍 (Streaming)  (0) 2025.11.13
라우트 세그먼트 옵션과 클라이언트 라우터 캐시  (0) 2025.11.13
'Frontend/Next.js' 카테고리의 다른 글
  • Next.js의 이미지 최적화
  • Next.js 앱 라우터 고급 라우팅 패턴
  • Next.js 앱 라우터의 에러 핸들링
  • 스트리밍 (Streaming)
고견
고견
개발 자국 남기기
  • 고견
    개발자국
    고견
  • 전체
    오늘
    어제
    • 분류 전체보기 (157) N
      • Frontend (29)
        • Next.js (16)
        • JavaScript (7)
      • CS (19) N
        • 자료구조 (9)
        • 알고리즘 (5)
        • 운영체제 (4) N
        • 네트워크 (1) N
      • TIL (93)
      • Dev Log (16)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    memory
    알고리즘
    Spa
    인터페이스
    javascript
    C
    배열
    앱 라우터
    페이지 라우터
    문자열
    emotion diary
    ai 감성 일기장
    react
    타입 좁히기
    typescript
    자료구조
    useState
    Trouble Shooting
    cs50
    클래스
    Next.js
    Pages Router
    제네릭
    CS
    바닐라 자바스크립트
    App Router
    algorithm
    트러블 슈팅
    함수 타입
    generic
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
고견
서버 액션 (Server Action)
상단으로

티스토리툴바