서버 액션 (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)
      • Frontend (29)
        • Next.js (16)
        • JavaScript (7)
      • CS (19)
        • 자료구조 (9)
        • 알고리즘 (5)
        • 운영체제 (4)
        • 네트워크 (1)
      • TIL (93)
      • Dev Log (16)
  • 블로그 메뉴

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

  • 공지사항

  • 인기 글

  • 태그

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

  • 최근 글

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

티스토리툴바