[Next.js] Server Actions, formData, useFormState

정호·2026년 4월 16일

Next.js

목록 보기
1/4

[Next.js] App Router 핵심 정리: Server Actions, formData, useFormState

Next.js의 App Router 환경에서 데이터를 주고받는 방식은 기존 리액트 방식과는 완전히 다릅니다. 핵심이 되는 세 가지 개념을 실제 코드 예시와 함께 정리합니다.


1. Server Actions (서버 액션)

"백엔드 로직을 프론트엔드 함수처럼 직접 호출하는 기술"

기존에는 데이터를 전송하기 위해 API 엔드포인트를 따로 만들었지만, 서버 액션은 함수 하나로 서버측 로직을 실행합니다.

  • 구현: 함수 내부에 'use server' 지시어를 선언합니다.
  • 장점: * API URL을 일일이 관리할 필요가 없습니다.
    • 민감한 DB 로직이 클라이언트에 노출되지 않아 보안에 강력합니다.
    • 자바스크립트가 로드되지 않은 환경에서도 HTML Form 표준에 따라 동작합니다.

2. formData (폼 데이터)

"폼에 담긴 모든 데이터를 한데 묶은 보따리"

서버 액션이 호출될 때 전달되는 인자로, 폼 내부의 모든 입력값을 가지고 있습니다.

  • 자동 수집:input 태그에 name 속성만 적어주면 제출 시점에 데이터를 자동으로 싹 긁어모읍니다.
  • 데이터 추출: formData.get('name값') 메서드로 원하는 데이터를 꺼낼 수 있습니다.
  • 💡 useRef와 차이점:
    • useRef (리모컨): 특정 입력창에 포커스를 주거나 직접 클릭을 발생시키는 등 '조작'이 목적입니다.
    • formData (보따리): 입력된 데이터들을 서버로 '전송'하기 위해 묶어주는 것이 목적입니다.

3. useFormState (폼 상태 관리)

"서버의 응답을 UI에 실시간으로 연결하는 통로"

서버 액션이 실행된 후, 서버에서 보내온 결과(성공/실패 메시지 등)를 클라이언트 화면에 보여주기 위해 사용하는 Hook입니다.

실제 구현 예시

// 1. 서버 액션 정의 (actions.js)
'use server';

export async function shareMeal(prevState, formData) {
  const title = formData.get('title');

  if (!title) {
    return { message: '제목을 입력해주세요!' }; // 에러 메시지 리턴
  }
  
  // DB 저장 로직 수행...
  return { message: '성공적으로 저장되었습니다.' };
}

// 2. 클라이언트 컴포넌트 (MealForm.js)
'use client';
import { useFormState } from 'react-dom';
import { shareMeal } from './actions';

export default function MealForm() {
  const [state, formAction] = useFormState(shareMeal, { message: null });

  return (
    <form action={formAction}>
      <input type="text" name="title" />
      {/* 서버에서 보낸 메시지가 state에 담겨 출력됨 */}
      {state.message && <p>{state.message}</p>}
      <button type="submit">제출</button>
    </form>
  );
}

4. revalidatePath: 데이터 최신화 (캐싱)

Next.js는 성능을 위해 페이지를 캐싱합니다. 데이터가 추가되었는데 화면이 바뀌지 않는다면 캐시 때문입니다.

  • 역할: revalidatePath('/meals')를 호출하면 해당 경로의 기존 캐시를 버리고 새로운 데이터를 다시 가져오도록 명령합니다.

  • 시점: 보통 서버 액션 안에서 DB 업데이트가 성공적으로 끝난 직후에 사용합니다.

5. 전체 데이터 흐름 요약

  1. 사용자: 폼 작성 후 제출 클릭.

  2. 클라이언트: 모든 데이터가 formData 보따리에 담김.

  3. 서버: Server Action 실행, DB 작업 수행.

  4. 서버: 작업 결과(메시지 등)를 반환하고 revalidatePath로 캐시 갱신.

  5. 클라이언트: useFormState가 리턴받은 결과를 화면에 표시.

profile
열심히 기록할 예정🙃

0개의 댓글